2016-10-27 3 views
0

Когда я устанавливаю контроллер на элементе, этот элемент и его дочерние объекты имеют доступ к области этого контроллера. Это имеет смысл.Как получить доступ к изолированной области действия в директиве, которая не использует шаблон

Однако, когда я добавляю директиву с изолированной областью в элемент (как атрибут), я бы ожидал, что этот элемент и его дочерние объекты будут иметь доступ к изолированной области видимости, но это не так.

HTML:

<body ng-app="testMod" ng-controller="ParentController"> 
    <div id="div1" ng-controller="MyController"> 
    <a href="#" ng-click="doit()">MyController</a> 
    </div> 
    <div id="div2" my-directive> 
    <a href="#" ng-click="doit()">MyDirective</a> 
    </div> 
</body> 

JS:

(function() { 
    angular 
    .module('testMod', []) 
    .controller('ParentController', ['$scope', function($scope) { 
     $scope.doit = function() { 
     console.log('ParentController scope') 
     } 
    }]) 
    .directive('myDirective', [function() { 
     return { 
     scope: {}, 
     restrict: 'A', 
     controller: 'MyController' 
     }; 
    }]) 
    .controller('MyController', ['$scope', function($scope) { 
     $scope.doit = function() { 
     console.log("MyController scope"); 
     }; 
    }]); 
})(); 

Когда я нажимаю на ссылку #div1 «s, MyController scope выводится, как я ожидал.

Когда я нажимаю на ссылку #div2, я ожидаю того же из-за изолированного объема, который я добавил в директиве, но вместо этого выводится ParentController scope.

Итак, какие элементы используют изолированный объем? К чему это относится? Могу ли я дать детям div[my-directive] доступ к нему?

Transclude не помогает мне здесь; Я хочу, чтобы у детей div[my-directive] был доступ к изолированной области действия директивы, а не к родительской области, но я не могу использовать шаблон в этом случае. Я по существу хочу, чтобы поведение контроллера от #div1, но мне нужна функция link, чтобы сделать некоторые манипуляции с DOM для детей.

ответ

0

Я нашел ответ на этот вопрос. Я объясню здесь, если это поможет кому-то в будущем.

Ответ заключается в том, чтобы использовать переход и использовать функцию transclude() для связывания содержимого элемента с изолированной областью. Это может быть сделано путем установки transclude: true на объекте директивы, и с помощью функции связи для вызова transclude() следующим образом:

(function() { 
    angular 
    .module('testMod', []) 
    .controller('ParentController', ['$scope', function($scope) { 
     $scope.doit = function() { 
     console.log('ParentController scope') 
     } 
    }]) 
    .directive('myDirective', [function() { 
     function link(scope, element, attrs, ctrl, transclude) { 
      transclude(scope, function(clone) { 
      element.append(clone); 
     });  
     } 
     return { 
     link: link, 
     scope: {}, 
     transclude: true, 
     restrict: 'A', 
     controller: 'MyController' 
     }; 
    }]) 
    .controller('MyController', ['$scope', function($scope) { 
     $scope.doit = function() { 
     console.log("MyController scope"); 
     }; 
    }]); 
})(); 

Как я пришел, чтобы понять это, что, когда вы устанавливаете transclude: true на сфере, Угловые удаляем содержимое элемента из DOM. При использовании шаблона вы должны использовать атрибут ng-transclude где-нибудь в шаблоне, чтобы указать Angular, где нужно вставить содержимое, в котором закончилось мое ограниченное понимание перехода (как я взял из Angular's Developer's Guide).

В этом случае мы не используем шаблон, поэтому ngTransclude не является опцией, и, кроме того, мы хотим привязываться к изолированной области, а не к исходной области содержимого (родительская область). Но мы можем использовать функцию transclude(), которую Angular предоставляет функции link(), чтобы установить ее вручную, привязывая извлеченное содержимое DOM к изолированной области.

This question дал мне ответ, и я нашел this section из Угловых документов, которые были полезны для понимания того, что я делаю.

Я создал jsfiddle для игры с этим.