Вложенные директивы, наследование области видимости и просмотр значений между родительским и дочерним

#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;
                }
            })
        }
    }
})
  

Вот мои вопросы / проблемы:

  1. Похоже, что дочерние директивы не могут наследовать область видимости от своей родительской директивы. Я попытался изменить объявления области видимости с isolate на true и т. Д., Но все равно не смог сослаться на radius переменную в дочерней функции link . Есть ли способ сделать это?
  2. В итоге я использовал 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).