personalizadas ejemplos directivas crear angularjs angularjs-directive angularjs-controller angularjs-compile

ejemplos - AngularJS: No se puede interpolar el atributo de la primera directiva a un segundo.(con el ejemplo de Plunker)



directivas angular 6 (5)

¿Escribiste la segunda directiva?

<second-directive two="''+ explicit +''"></second-directive>

Para que funcione el código anterior, debe tener una configuración de objeto de ámbito aislado en la segunda directiva, consulte el plunkr a continuación.

http://plnkr.co/edit/YP2h3MOhsrjN5sLUNQs6?p=preview

Referencia

Referencia plunker: http://plnkr.co/edit/otv5mVVQ36iPi3Mp0FYw?p=preview

Explicación del problema

Supongamos que tenemos dos directivas, first-directive y second-directive . Ahora supongamos que solo tenemos acceso a la first-directive que esperamos ajustar la second-directive y le transmitimos nuestros propios atributos manipulados.

app.directive(''firstDirective'', function() { return { scope: true, priority: 1000, transclude: true, template: function(element,attributes){ console.log(''template'') return ''<second-directive two="{{one}}"></second-directive>'' }, compile: function(element,attributes) { console.log(''compile'') return { pre: function(scope){ scope.one = ''foo'' console.log(''cpre'') }, post: function(scope){ scope.one = ''foo'' console.log(''cpost'') }, } }, controller: [''$scope'',''$attrs'',function($scope,$attrs){ console.log(''controller''); $scope.one = ''foo''; }], } }) app.directive(''secondDirective'',function(){ return { template: function (element,attributes){ console.log(attributes.two) //{{one}} not ''foo'' or ''test'' return ''Hello {{two}}'' } } });

first-directive se llama de la siguiente manera:

<first-directive one=''test''></first-directive>

La salida console.log es la siguiente:

template compile {{one}} controller cpre cpost

Entonces de esto he aprendido que la plantilla se llama antes de compilar. ¡Esto es algo peculiar de mis ojos de principiante porque no hay forma de manipular el valor pasado por la función de plantilla a través de un enlace de compilación, controlador, pre o post!

La pregunta es esta:

¿Cómo puedo llamar a la second-directive con el valor de atributo dinámico que quiero? Tenga en cuenta que la second-directive es completamente independiente y no podemos agregar código allí.

PD: una idea posible que tengo es llamar a la segunda directiva de la siguiente manera:

template: function(element,attributes){ console.log(''template'') var explicit = ???? /* how to access scope? */ return ''<second-directive two="''+ explicit +''"></second-directive>'' },

o alternativamente

template: function(element,attributes){ console.log(''template'') return $interpolate(''<second-directive two="{{one}}"></second-directive>'')(scopeObj) /* how does one access scopeObj with current scope values here? */ },

Sin embargo, nuevamente, no estoy seguro de cómo hacer que se pase el valor a la primera directiva antes de que se llame a cualquiera de las otras funciones. El controlador tiene acceso a $ scope y se llama plantilla DESPUÉS.

Tus sugerencias muy apreciadas.


Bueno, si solo quiere pasar los datos de la primera directiva a la plantilla de la segunda directiva, entonces puede agregar el atributo de dinámica en el controlador de la primera directiva usando
this.fromFirstDir = "puedes pasar de aquí"

primer controlador directivo:

controller: [''$scope'',''$attrs'',function($scope,$attrs){ console.log(''controller''); $scope.one = ''foo''; this.fromFirstDir = "you can pass from here" }], }

Luego, utilizando el atributo require en la segunda dirección para el controlador de la primera directiva, puede acceder a este atributo dinámico desde la función de enlace de la segunda directiva Directire usando el controlador transferido a la función de enlace. Finalmente asigne esos atributos al alcance local pasado a la función de enlace.

app.directive(''secondDirective'',function(){ return { scope: {twoData : ''@twoData''}, require : ''^firstDirective'', template: function (element,attributes){ console.log(attributes.two) //{{one}} not ''foo'' or ''test'' return ''Hello <b>{{fromFirstDir}}</b>'' }, link : function(scope,element,attr,firstDirCtrl){ console.log("===",firstDirCtrl.fromFirstDir) scope.fromFirstDir = firstDirCtrl.fromFirstDir; } } });

De esta manera, esos atributos dinámicos están disponibles para su segunda directiva.

Aquí está el violín final.

Espero que esto te ayudará.


Estoy usando su pregunta para aprender, pero pude encontrar esto, que podría funcionar para usted:

app.directive("tryThis", function($compile){ return{ scope: { one: ''@'', }, link: function(scope, element){ var template = ''<second-directive two="''+scope.one+''"></second-directive>''; var linkFn = $compile(template); var content = linkFn(scope); element.append(content); } } });

Plunkr está aquí , tenga en cuenta que la test está registrada en la consola ahora en lugar de {{one}} . Si secondDirective tiene un alcance aislado, la test se mostrará en la pantalla.

Este enlace también me ayudó a comprender conceptualmente el problema al que se enfrenta, dando un contexto al tema del paso "no hay alcance durante la compilación". No estoy seguro de que haya una forma de evitarlo.


No tiene (no puede) tener acceso al alcance dentro de la plantilla (porque no hay alcance en ese momento). La plantilla se utiliza para crear uno o más elementos y luego están vinculados a un alcance (después de tener sus controladores instanciados, si hay alguno).

Hay muchas maneras de pasar valores entre directivas y cada una es más adecuada para fines particulares. El más simple (pero no necesariamente el mejor, según los detalles de su caso de uso) es asignar un valor en un ámbito de la directiva contenedora y dejar que la directiva interna lo lea fuera del alcance:

<!-- HTML --> <one for-two="{{test}}"></one> // JS angular. module(''myApp'', []). directive(''one'', oneDirective). directive(''two'', twoDirective); function oneDirective() { return { restrict: ''E'', scope: true, link: function onePostLink(scope, elem, attrs) { scope.two = attrs.forTwo; }, template: ''<two></two>'' }; } function twoDirective() { return { restrict: ''E'', template: ''Hello, {{two}} !'' }; }


Has transclude: true pero no lo estás usando en la plantilla. ¿No puedes usar este marcado y tener la plantilla para el uso de la primera directiva <ng-transclude> ? Tiene scope: true por lo que podría manipular la propiedad del padre / controlador y los cambios se propagarían a ambas directivas.

margen

<first-directive one="test"> <second-directive two="test"></second-directive> </first-directive>

plantilla para primera directiva

template: `<div> my first directive content <ng-transclude></ng-transclude> </div>`;

https://docs.angularjs.org/api/ng/directive/ngTransclude