#angularjs #angularjs-directive #angularjs-scope
#angularjs #angularjs-директива #angularjs-область видимости
Вопрос:
Я пытаюсь настроить пару директив, которые имеют иерархию родительский / дочерний, и я сталкиваюсь с некоторыми проблемами, понимая, как область действия обрабатывается с помощью вложенных директив. В конечном счете, я хотел бы, чтобы дочерняя директива реагировала на изменения в области действия родительской директивы. Вот мой пример, который также находится в jsfiddle (http://jsfiddle.net/4rt3b/48 /)
HTML:
<div ng-app='app' ng-controller='MainCtrl'>
Radius : <input ng-model='myRadius' ng-init="myRadius=100"/>
<parent radius="myRadius">
<child pi="3.14"></child>
</parent>
</div>
JS
var app = angular.module('app',[]);
app.controller('MainCtrl', function($scope){
});
app.directive('parent', function(){
return {
restrict : "AE",
replace : true,
transclude : true,
scope : {
radius : "="
},
template : "<div>Parent controller's radius is {{radius}}<div ng-transclude></div></div>",
controller : function($scope){
this.getRadius = function(){
return $scope.radius;
}
}
}
})
app.directive('child', function(){
return {
restrict : "AE",
require : "^parent",
replace : true,
scope : {
pi : "="
},
template : "<div>Child directive's pi is {{pi}} and area is {{area}}</div>",
link: function(scope, elem, attr, parentCtrl){
// This works
scope.area = 2 * scope.pi * parentCtrl.getRadius();
// This never seems to trigger
scope.$watch('parentCtrl.getRadius()', function(newVal){
if (newVal){
scope.area=2 * scope.pi * newVal;
}
})
}
}
})
Вот мои вопросы / проблемы:
- Похоже, что дочерние директивы не могут наследовать область видимости от своей родительской директивы. Я попытался изменить объявления области видимости с isolate на true и т. Д., Но все равно не смог сослаться на
radius
переменную в дочерней функции link . Есть ли способ сделать это? - В итоге я использовал
require
параметр для совместного использования контроллеров из родительской в дочернюю директиву. Похоже, это работает, однако, похоже, я не могу $watch изменения в родительском. Введите значение дляradius
, и вы увидите, что область не обновляется. Как я могу $watch изменения в модели родительской директивы?
Спасибо!
Ответ №1:
Понял это. Наблюдатель должен быть объявлен следующим образом:
scope.$watch(
function(){
return parentCtrl.getRadius();
},
function(newVal){
if (newVal){
scope.area=2 * scope.pi * newVal
}
})
Ответ №2:
Вы также можете настроить метод в родительском контроллере для получения дочерней области видимости в качестве аргумента, поскольку он передается по ссылке. Метод в родительском контроллере просто присваивает дочернюю область свойству своей области, т.Е.. scope.child_scope. Затем сохраните $watch в родительском контроллере и установите scope.child_scope.area = scope.child_scope.pi * newVal (внутри этого $watch).