Будучи обернутым директивой, как я могу получить доступ к ее области действия?
-
21-12-2019 - |
Вопрос
Как я могу получить доступ к области изоляции директивы в теле директивы?Мой DOM выглядит так:
<div ng-app="app">
<directive>
<p>boolProperty: {{boolProperty|json}}</p>
</directive>
</div>
А boolProperty
назначается внутри директивы link
функция:
angular.module("app", []).directive("directive", function() {
return {
scope: {},
link: function($scope) {
$scope.boolProperty = true;
}
};
});
Проблема в том, что ребенок <p>
внутри директивы привязывается к директиве родитель область действия, а не изолированная область действия директивы.Как я могу это преодолеть?
Решение
Вы забыли о двух вещах:
- По умолчанию AngularJS использует ограничение атрибутов, поэтому в вашем случае в определении директивы вы должны указать
restrict: "E"
- Вы должны использовать дочернюю область, но не изолированную.Итак, установите
scope: true
для наследования от родительской области представления.
См. обновленную скрипку http://jsfiddle.net/Y9g4q/1/.
Удачи.
Другие советы
В вашем коде есть пара проблем.
- Опция ограничения по умолчанию:
A
for атрибут, так что ваша директива в любом случае не будет скомпилирована, поскольку вы используете ее как элемент.Использоватьrestrict: 'E'
чтобы это работало. Согласно документации, область действия включенного элемента не является дочерней областью директивы, а является родственной.Так
boolProperty
всегда будет неопределенным или пустым.Поэтому вам нужно подняться на уровень выше и найти подходящего брата.<div ng-app="app"> <directive> <p>boolProperty: {{$parent.$$childHead.boolProperty}}</p> </directive> </div>
и необходимо использовать включение в директиве как:
angular.module("app", []).directive("directive", function() {
return {
restrict: 'E',
scope: {},
transclude: true,
template: '<div ng-transclude></div>',
link: function(scope) {
scope.boolProperty = true;
}
};
});
Однако этот подход нецелесообразен и позже сломается, если вы добавите новый контроллер перед директивой, поскольку включенная область становится вторым родственным элементом, в отличие от первого, как раньше.
<div ng-app="app">
<div ng-controller="OneCtrl"></div>
<directive>
<p>boolProperty: {{$parent.$$childHead.boolProperty || $parent.$$childHead.$$nextSibling.boolProperty}}</p>
</directive>
</div>
Здесь Рабочая демонстрация.Подход, о котором я упомянул, не идеален, поэтому используйте его на свой страх и риск.Ответ @CodeHater — это тот, который вам следует использовать.Я просто хотел объяснить, почему у вас это не сработало.
Из документы:
As the name suggests, the isolate scope of the directive isolates everything except models that you've explicitly added to the scope: {} hash object. This is helpful when building reusable components because it prevents a component from changing your model state except for the models that you explicitly pass in.
Кажется, вам нужно будет явно добавить boolProperty
к scope
.
<div ng-app="app" ng-controller="ctrl">
<directive bool="boolProperty">
<p>boolProperty: {{boolProperty|json}}</p>
</directive>
</div>
JS
angular.module("app", []).controller("ctrl",function($scope){
$scope.boolProperty = false;
}).directive("directive", function() {
return {
restrict:"E",
scope: {boolProperty:'=bool'},
link: function($scope) {
$scope.boolProperty = "i'm a boolean property";
}
};
});
Здесь обновлено скрипка.