#javascript #angularjs #scope #angularjs-directive
#javascript #angularjs #область действия #angularjs-директива
Вопрос:
Я новичок в AngularJS, и, изучая его, я наткнулся на замечательный пост о том, как области вложены и наследуются в HTML-разметке: Понимание областей
Также я просмотрел этот Plunker, чтобы понять, о чем говорится в приведенном выше сообщении.
Я создал этот JSFiddle, чтобы понять вышеупомянутые концепции.
HTML:
<body ng-app="myApp">
<h1>Hello AngularJS!</h1>
<div ng-controller="myCtrl">{{hello}}
<div anchor-link>
<a href="javascript:;">click me</a>
<div ng-show="t.show">show me</div>
<div ng-hide="t.show">hide me</div>
</div>
</div>
</body>
JS:
var app = angular.module("myApp", []);
app.controller('myCtrl', function ($scope) {
$scope.hello = 'Hello World!';
$scope.t = {
show: true
};
});
app.directive('anchorLink', function () {
return {
restrict: 'EA',
link: function (scope, elem, attr) {
elem.on('click', function () {
scope.t.show = !scope.t.show;
});
}
};
});
Теперь мой вопрос:
-
Почему двусторонняя привязка данных не работает в моем fiddle? Разве область действия моей пользовательской директивы не должна наследоваться от своего родителя (т. Е. контроллера)?
-
Если я использую
$scope.t
в качестве объекта в области контроллера. тогда почему он не переключает «показать мне» и «скрыть меня» divs? Я также пытался использоватьscope: true
в своей пользовательской директиве, но это все еще не работает. -
Это потому, что
scope
в моей функции link не наследуется прототипически? -
Действительно ли это изменяет
$scope.t
объект родительской области?
Ответ №1:
Итак, что вам нужно сделать, это:
http://jsfiddle.net/DkFx9/
Здесь происходит то, что вы используете click
обработчик событий jQuery для обработки события click и изменения scope
переменной в обработчике. Проблема с этим заключается в том, что у angular нет способа узнать, что что-то в scope изменилось, и, следовательно, ему необходимо обновить представления.
Обычно, когда вы делаете что-то подобное, используя директиву angular like ng-click="t.show = !t.show"
, angular знает, что некоторые даже произошли через angular, и запускает цикл дайджеста, чтобы выполнить грязную проверку и обновить связанные представления.
В вашем случае мы должны сообщить angular, что что-то происходит, и он должен запустить цикл дайджеста. scope.$apply
берет фрагмент кода, который вы хотите выполнить, а затем просит angular запустить цикл дайджеста и обновить представления, которые необходимо обновить.
Надеюсь, это поможет.
Комментарии:
1. О!! Хорошо. Но есть ли какой-либо другой способ, кроме использования $apply? А как насчет моего 4-го вопроса. Даже если привязка данных не происходит по причинам, объясненным вами .. действительно ли значение меняется в родительской области или нет? Я думаю, да, поскольку оповещения показывают обновленное значение в обработчике событий
2. Также могу ли я изолировать область, чтобы происходило привязывание? или это не повлияет по тем же причинам, которые вы объяснили?
3. Итак, запустите JSfiddle, которым я поделился. И вы заметите, что значения действительно меняются. Значения меняются, да. И происходит привязка данных. Единственная проблема заключалась в том, что объект Javascript был изменен, но Angular не знает об этом, поэтому он не может обновлять представления и выполнять манипуляции с DOM, как того требуют
ng-hide
иng-show
. Итак, по сути,t
объект области видимости контроллера имеет новое измененное значение, но значение не было отражено в представлении из-за того, что цикл дайджеста не был запущен.4. Если вы изолируете область действия, то ничего не будет отражено снаружи, т. е. в области действия контроллера (потому что директива теперь имеет изолированную область действия).