Użycie symboli „@”, „&”, „=” i „>” w wiązaniu zakresu dyrektywy niestandardowej: AngularJS


151

Dużo czytałem o używaniu tych symboli we wdrażaniu niestandardowych dyrektyw w AngularJS, ale koncepcja nadal nie jest dla mnie jasna. Mam na myśli, co to znaczy, jeśli używam jednej z wartości zakresu w dyrektywie niestandardowej?

var mainApp = angular.module("mainApp", []);
mainApp.directive('modalView',function(){
  return{
     restrict:'E',
     scope:'@' OR scope:'&' OR scope:'=' OR scope:'>' OR scope:true
  }
});

Co dokładnie robimy z lunetą?

Nie jestem też pewien, czy „zakres: '>'” istnieje w oficjalnej dokumentacji, czy nie. Został użyty w moim projekcie.

Edycja-1

Użycie „zakresu: '>'” było problemem w moim projekcie i zostało naprawione.

Odpowiedzi:


116

W dyrektywie AngularJS zakres umożliwia dostęp do danych w atrybutach elementu, do którego ta dyrektywa jest stosowana.

Najlepiej ilustruje to przykład:

<div my-customer name="Customer XYZ"></div>

a definicja dyrektywy:

angular.module('myModule', [])
.directive('myCustomer', function() {
  return {
    restrict: 'E',
    scope: {
      customerName: '@name'
    },
    controllerAs: 'vm',
    bindToController: true,
    controller: ['$http', function($http) {
      var vm = this;

      vm.doStuff = function(pane) {
        console.log(vm.customerName);
      };
    }],
    link: function(scope, element, attrs) {
      console.log(scope.customerName);
    }
  };
});

Gdy scopewłaściwość jest używana, dyrektywa znajduje się w tak zwanym trybie „izolowanego zakresu”, co oznacza, że ​​nie ma bezpośredniego dostępu do zakresu kontrolera nadrzędnego.

Mówiąc najprościej, znaczenie symboli wiążących jest następujące:

someObject: '=' (dwukierunkowe wiązanie danych)

someString: '@'(przekazywane bezpośrednio lub przez interpolację z notacją z podwójnymi nawiasami klamrowymi {{}})

someExpression: '&'(np. hideDialog())

Ta informacja jest obecna na stronie dokumentacji dyrektywy AngularJS , chociaż jest nieco rozrzucona po całej stronie.

Symbol >nie jest częścią składni.

Jednak <istnieje jako część powiązań komponentu AngularJS i oznacza wiązanie w jedną stronę.


6
O co chodzi @??
Homer

9
Warto dodać, że <jest nie tylko kompatybilny z komponentami w 1.5, ale jest również zgodny z dyrektywami. @Homer ?oznacza atrybut jako opcjonalny .
Jens Bodal

171

> nie ma w dokumentacji.

< służy do wiązania w jedną stronę.

@wiązanie służy do przekazywania ciągów. Te ciągi obsługują {{}}wyrażenia dla wartości interpolowanych.

=powiązanie jest dla dwukierunkowego powiązania modelu. Model w zakresie nadrzędnym jest powiązany z modelem w izolowanym zakresie dyrektywy.

& wiązanie służy do przekazywania metody do zakresu dyrektywy, aby można ją było wywołać w ramach dyrektywy.

Kiedy ustawiamy zakres: true w dyrektywie, Angular js utworzy nowy zakres dla tej dyrektywy. Oznacza to, że wszelkie zmiany wprowadzone w zakresie dyrektywy nie zostaną odzwierciedlone z powrotem w kontrolerze nadrzędnym.


47

< jednokierunkowe wiązanie

= dwukierunkowe wiązanie

& powiązanie funkcji

@ przekazują tylko ciągi


6
Nie ma sensu powtarzać tej samej odpowiedzi, przepraszam, że nie ta sama odpowiedź. Wydaje się, że to wyciągnięta informacja z powyższych odpowiedzi.
MAC,

19
czasami krótsza odpowiedź jest bardziej praktyczna!
Marwen Trabelsi

nie trzeba dodawać śmieciowych informacji, jeśli możesz to wyjaśnić w kilku krótkich linijkach :)
Marwen Trabelsi

1
Byłoby to lepsze jako zmiana prowadząca do jednej z wyżej głosowanych opcji.
N-zjadł

3

Kiedy tworzymy dyrektywę klienta, zakres dyrektywy może znajdować się w zakresie izolowanym, co oznacza, że ​​dyrektywa nie dzieli zakresu z kontrolerem; zarówno dyrektywa, jak i kontroler mają swój własny zakres. Jednak dane można przekazać do zakresu dyrektywy na trzy możliwe sposoby.

  1. Dane mogą być przekazywane jako ciąg przy użyciu @literału ciągu, wartości ciągu przekazywania, powiązania w jedną stronę.
  2. Dane mogą być przekazywane jako obiekt przy użyciu =literału ciągu, obiektu przekazywania, wiązania na 2 sposoby.
  3. Dane mogą być przekazane jako funkcja &literał ciągu, wywołuje funkcję zewnętrzną, może przekazywać dane z dyrektywy do kontrolera.

2

Dokumentacja AngularJS dotycząca dyrektyw jest całkiem dobrze napisana, jeśli chodzi o znaczenie symboli.

Żeby było jasne, nie możesz po prostu mieć

scope: '@'

w definicji dyrektywy. Musisz mieć właściwości, do których mają zastosowanie te powiązania, na przykład:

scope: {
    myProperty: '@'
}

Gorąco zachęcam do zapoznania się z dokumentacją i samouczkami na stronie. Jest o wiele więcej informacji, które musisz wiedzieć o izolowanych zakresach i innych tematach.

Oto bezpośredni cytat z powyższej strony, dotyczący wartości scope:

Właściwość scope może mieć wartość true, obiekt lub fałszywą wartość:

  • fałsz : dla dyrektywy nie zostanie utworzony żaden zakres. Dyrektywa będzie wykorzystywać zakres jej rodzica.

  • true: Nowy zakres potomny, który prototypowo dziedziczy po swoim rodzicu, zostanie utworzony dla elementu dyrektywy. Jeśli wiele dyrektyw dotyczących tego samego elementu żąda nowego zakresu, tworzony jest tylko jeden nowy zakres. Nowa reguła zakresu nie ma zastosowania do katalogu głównego szablonu, ponieważ katalog główny szablonu zawsze otrzymuje nowy zakres.

  • {...} (skrót obiektu) : dla elementu dyrektywy tworzony jest nowy zakres „izolowania”. Zakres „izolowany” różni się od zakresu normalnego tym, że nie dziedziczy on prototypowo po zakresie nadrzędnym. Jest to przydatne podczas tworzenia komponentów wielokrotnego użytku, które nie powinny przypadkowo odczytywać ani modyfikować danych w zakresie nadrzędnym.

Pobrano 13.02.2017 z https://code.angularjs.org/1.4.11/docs/api/ng/service/ $ compile # -scope-, na licencji CC-by-SA 3.0


0

Miałem problem z przypisaniem wartości do któregokolwiek z symboli w AngularJS 1.6. W ogóle nie uzyskałem żadnej wartości undefined, chociaż zrobiłem to dokładnie w taki sam sposób, jak inne powiązania w tym samym pliku, które działały.

Problem polegał na tym, że nazwa mojej zmiennej miała podkreślenie.

To się nie udaje:

bindings: { import_nr: '='}

To działa:

bindings: { importnr: '='}

(Nie do końca związane z pierwotnym pytaniem, ale był to jeden z najlepszych wyników wyszukiwania, kiedy sprawdzałem, więc mam nadzieję, że pomoże to komuś z tym samym problemem).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.