Al estar envuelto por una directiva, ¿cómo puedo acceder a su alcance?
-
21-12-2019 - |
Pregunta
¿Cómo puedo acceder al alcance aislado de la directiva en el cuerpo de la directiva?Mi DOM se ve así:
<div ng-app="app">
<directive>
<p>boolProperty: {{boolProperty|json}}</p>
</directive>
</div>
El boolProperty
se asigna dentro de la directiva link
función:
angular.module("app", []).directive("directive", function() {
return {
scope: {},
link: function($scope) {
$scope.boolProperty = true;
}
};
});
El problema es que el niño <p>
dentro de la directiva se une a la directiva padre ámbito de aplicación, no el ámbito aislado de la directiva.¿Cómo puedo superar esto?
Solución
Te olvidaste de dos cosas:
- De forma predeterminada, AngularJS usa restricción de atributos, por lo que en su caso, en la definición de la directiva, debe especificar
restrict: "E"
- Debe utilizar un ámbito secundario, pero no aislado.Así que listo
scope: true
para heredar del alcance de la vista principal.
Ver violín actualizado http://jsfiddle.net/Y9g4q/1/.
Buena suerte.
Otros consejos
Hay un par de problemas en su código.
- La opción de restricción predeterminada es
A
para el atributo, de todos modos su directiva no se compilará porque la está usando como elemento.Usarrestrict: 'E'
para que funcione. Según la documentación, el alcance del elemento transcluido no es un alcance secundario de la directiva sino uno hermano.Entonces
boolProperty
siempre estará indefinido o vacío.Entonces tienes que subir el nivel de alcance y encontrar al hermano adecuado.<div ng-app="app"> <directive> <p>boolProperty: {{$parent.$$childHead.boolProperty}}</p> </directive> </div>
y necesidad de utilizar la transclusión en la directiva como:
angular.module("app", []).directive("directive", function() {
return {
restrict: 'E',
scope: {},
transclude: true,
template: '<div ng-transclude></div>',
link: function(scope) {
scope.boolProperty = true;
}
};
});
Sin embargo, este enfoque no es aconsejable y se interrumpe más tarde si agrega un nuevo controlador antes de la directiva porque el alcance transcluido se convierte en un segundo hermano, a diferencia del primero como antes.
<div ng-app="app">
<div ng-controller="OneCtrl"></div>
<directive>
<p>boolProperty: {{$parent.$$childHead.boolProperty || $parent.$$childHead.$$nextSibling.boolProperty}}</p>
</directive>
</div>
Aquí está el Demostración de trabajo.El enfoque que mencioné no es ideal, así que úselo bajo su propio riesgo.La respuesta de @CodeHater es la que debes elegir.Sólo quería explicarte por qué no te funcionó.
Desde el documentos:
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.
Parece que necesitarías agregar explícitamente boolProperty
a 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";
}
};
});
Aquí está actualizado violín.