Mylić o AngularJS transcluded i izolować lunety i wiązania
[13]}staram się zrozumieć zakres modeli i ich powiązania w odniesieniu do dyrektyw, które mają ograniczony zakres.
Rozumiem, że ograniczenie zakresu dyrektywy oznacza, że kontroler.$ scope and directive.scope to już nie to samo. Jestem jednak zdezorientowany tym, jak umieszczenie modeli w szablonie dyrektywy lub w html wpływa na powiązanie danych. Czuję, że brakuje mi czegoś bardzo fundamentalnego i aby ruszyć dalej, muszę zrozumieć to.
Weź następujący kod (tutaj: http://jsfiddle.net/2ams6/)
JavaScript
var app = angular.module('app',[]);
app.controller('Ctrl',function($scope){
});
app.directive('testel', function(){
return {
restrict: 'E',
scope: {
title: '@'
},
transclude: true,
template: '<div ng-transclude>'+
'<h3>Template title: {{title}}</h3>' +
'<h3>Template data.title:{{data.title}}</h3>' +
'</div>'
}
});
HTML
<div ng-app='app'>
<div ng-controller="Ctrl">
<input ng-model="data.title">
<testel title="{{data.title}}">
<h3>Transclude title:{{title}}</span></h3>
<h3>Transclude data.title:{{data.title}}</h3>
</testel>
</div>
</div>
Model aktualizuje tylko {{title}}
wewnątrz szablonu i {{data.title}}
w transclusion. dlaczego nie {{title}}
w transclusion ani {{data.title}}
w szablonie?
Przenoszenie wejścia do wewnątrz transclusion tak (tutaj: http://jsfiddle.net/eV8q8/1/):
<div ng-controller="Ctrl">
<testel title="{{data.title}}">
<input ng-model="data.title">
<h3>Transclude title: <span style="color:red">{{title}}</span></h3>
<h3>Transclude data.title: <span style="color:red">{{data.title}}</span></h3>
</testel>
</div>
Teraz oznacza tylko transclude {{data:title}}
dostaje aktualizacja. dlaczego nie szablon {{title}}
lub {{data.title}}
, ani nie transclude {{title}}
?
I na koniec przesunięcie wejścia do wewnątrz szablonu, w ten sposób (tutaj: http://jsfiddle.net/4ngmf/2/):
template: '<div ng-transclude>' +
'<input ng-model="data.title" />' +
'<h3>Template title: {{title}}</h3>' +
'<h3>Template data.title: {{data.title}}</h3>' +
'</div>'
Teraz oznacza, że tylko szablon {{data.title}}
zostanie zaktualizowany. znowu, dlaczego nie pozostałe 3 wiązania?
Mam nadzieję, że coś jest oczywiste patrząc mi w twarz i brakuje mi tego. Jeśli mnie do tego zmusisz, postawię ci piwo, albo dam ci punkty, albo coś takiego. Wielkie dzięki.
3 answers
Twoje skrzypce tworzą trzy zakresy:
- zakres związany z kontrolerem
Ctrl
, ze względu nang-controller
- dyrektywa transkludowana zakres, ze względu na
transclude: true
- dyrektywa izoluje zakres, ze względu na
scope: { ... }
W fiddle1, przed wpisaniem czegokolwiek w pole tekstowe mamy następujące:
Zakres 003 to zakres związany z kontrolerem. Ponieważ nie wpisaliśmy jeszcze w pole tekstowe, nie ma właściwości data
. W izolowanym zakresie 004 widzimy, że została utworzona właściwość title
, ale jest ona pusta. Jest pusty, ponieważ zakres nadrzędny nie posiada jeszcze właściwości data.title
.
Po wpisaniu my title
W pole tekstowe mamy teraz:
Kontroler scope 003 ma teraz nową właściwość obiektu data
(dlatego jest koloru żółtego), która ma właściwość title
ustawioną na my title
. Ponieważ właściwość isolate scope title
jest jednokierunkową bazą danych do interpolowanej wartości data.title
, otrzymuje również wartość my title
(wartość jest zabarwiona na Żółto, ponieważ się zmieniła).
Transkludowany zakres prototypowo dziedziczy z zakresu kontrolera, więc wewnątrz transkludowanego HTML, angular może podążać za łańcuchem prototypów i znaleźć $scope.data.title
w zakresie nadrzędnym (ale $scope.title
tam nie istnieje).
Zakres izolowany ma dostęp tylko do własnych właściwości, stąd tylko do właściwości title
.
W fiddle2, przed wpisaniem mamy taki sam obrazek jak w fiddle1.
Po wpisaniu my title
:
Zauważ, gdzie pojawiła się nowa właściwość data.title
-- na transkludowanym zakresie. Zakres izolowany nadal szuka data.title
w zakresie kontrolera, ale tym razem go tam nie ma, więc jego wartość właściwości title
pozostaje pusta.
W fiddle3, przed wpisaniem mamy taki sam obrazek jak w fiddle1.
Po wpisaniu my title
:
Zwróć uwagę, gdzie pojawiła się nowa właściwość data.title
-- na izolowanym obszarze. Nikt inny zakresy mają dostęp do zakresu izolowanego, więc łańcuch my title
nie pojawi się nigdzie indziej.
Aktualizacja dla Angular v1.2:
Ze zmianąeed299a kątowy teraz czyści punkt transcluzji przed transcludacją, więc części Template title: ...
i Template data.title: ...
nie pojawią się, chyba że zmodyfikujesz szablon tak, aby ng-transclude
był sam w sobie, na przykład: {]}
'<h3>Template title: <span style="color:red">{{title}}</span></h3>' +
'<h3>Template data.title: <span style="color:red">{{data.title}}</span></h3>' +
'<div ng-transclude></div>'
W poniższej aktualizacji dla Angular v1. 3 wprowadzono tę zmianę szablonu.
Aktualizacja dla Kątowa v1.3+:
Od wersji Angular v1. 3, transkludowany zakres jest teraz potomkiem izolowanego zakresu dyrektywy, a nie potomkiem zakresu kontrolera. Więc w fiddle1, zanim cokolwiek napiszemy:
Zdjęcia w tej aktualizacji są rysowane za pomocą narzędzia Peri$scope, więc zdjęcia są nieco inne. @
wskazuje, że mamy właściwość isolate scope, która używa składni @
, a różowe tło oznacza, że narzędzie nie było w stanie aby znaleźć odniesienie przodka dla mapowania (co jest prawdą, ponieważ nie wpisaliśmy jeszcze niczego do pola tekstowego).
Po wpisaniu my title
W pole tekstowe mamy teraz:
Właściwości izolujące, które używają wiązania @
zawsze będą wyświetlać wynik interpolowanego ciągu znaków w zakresie izolowania po symbolu @
. Peri$scope była również w stanie znaleźć tę dokładną wartość łańcuchową w zakresie nadrzędnym, więc pokazuje również odniesienie do tej właściwości.
W fiddle 2, przed wpisaniem mamy taki sam obrazek jak w fiddle1.
Po wpisaniu my title
:
Zauważ, gdzie pojawiła się nowa właściwość data.title
-- na transkludowanym zakresie. Zakres izolowany nadal szuka data.title
w zakresie kontrolera, ale tym razem go tam nie ma, więc jego wartość właściwości title
pozostaje pusta.
W fiddle3, przed wpisaniem mamy taki sam obrazek jak w fiddle1.
Po wpisaniu my title
:
Zwróć uwagę, gdzie pojawiła się nowa właściwość data.title
-- na izolowanym obszarze. Nawet jeśli transkludowany zakres ma dostęp do izolowanego zakresu poprzez relację $parent
, nie będzie tam szukał title
ani data.title
-- będzie szukał tylko w zakresie kontrolera (tzn. będzie podążał za dziedziczeniem prototypowym), a zakres kontrolera nie ma zdefiniowanych tych właściwości.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-31 03:34:02
Po przeczytaniu wszystkich przedstawionych odpowiedzi, w tym fantastycznych schematów Marka, to jest moje zrozumienie zakresu i jest dziedziczenie na moje pytanie. Byłbym wdzięczny za komentarze na temat tego, gdzie ten diagram spada, w celu mogę zaktualizować odpowiednio. Mam nadzieję, że po prostu daje inny pogląd na to, co przedstawił Mark:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-24 14:10:47
Dobrze zapytany, btw! Mam nadzieję, że moja odpowiedź jest równie wymowna..
Odpowiedź ma związek z tym, jak elementy transkludowane uzyskują swój zakres.
Podsumowując, masz dwa zakresy:
- zakres kontrolera, który ma
$scope.data.title
. (Domyślnie dodany przez twójinput
element) - zakres dyrektywy, który ma
$scope.title
.
Po zmianie kontrolera $scope.data.title
zmienia się również dyrektywa $scope.title
.
Masz też dwie sekcje HTML, transkludowaną i szablon. To, co się dzieje, to fakt, że transkludowany HTML znajduje się w zakresie kontrolera , A szablon HTML znajduje się w zakresie dyrektywy . Tak więc transkludowany HTML nie wie nic o title
, a zakres szablonów nie wie nic o data.title
Właśnie do tego była przeznaczona Transclusion - , aby umożliwić potomnym elementom dyrektywy zachowanie ich nadrzędnego zakresu , w tym przypadku zakresu kontrolera. Według projektu, transkludowane elementy nie wiedzą, że ich w dyrektywie, a więc nie mają dostępu do zakresu dyrektywy.
Z drugiej strony Szablony dyrektyw będą miały dostęp tylko do zakresu dyrektywy.Zmieniłem trochę Twój kod, aby nazwy były bardziej przejrzyste (ta sama funkcjonalność)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-20 16:22:33