w3schools tag eliminar create and javascript angularjs angularjs-directive angularjs-scope

javascript - tag - ¿Cómo obtener un enlace de datos bidireccional en una directiva*sin*un alcance aislado?



jquery create element and append (4)

La respuesta de pixelbits me ayudó a resolver esto a lo grande, pero considerada como una respuesta directa a mi pregunta original, parece demasiado complicada. Después de verlo, la solución es bastante simple.

Tome una directiva con un alcance aislado como este:

scope: { model: ''=myModel'' }, link: function(scope, element, attr) { //... }

Lo siguiente es equivalente, excepto que el alcance no está aislado:

scope: true, link: function(scope, element, attr) { scope.model = scope.$parent.$eval(attr.myModel); //... }

Vea un ejemplo de trabajo aquí: http://jsfiddle.net/mhelvens/SZ55R/1/

El uso del scope: { ... } en una directiva introduce un ámbito aislado, que no se hereda de forma prototípica de su ámbito primario. Pero siempre lo he usado por una razón diferente: una forma conveniente de declarar atributos HTML con enlace de datos bidireccional:

scope: { attr1: ''='', attr2: ''?='' }

Para obtener un ámbito no aislado, debe utilizar scope: true , que no ofrece la oportunidad de declarar dichos atributos. Ahora me encuentro necesitando una directiva con un alcance no aislado, pero con enlace bidireccional. ¿Cuál es la mejor manera de lograr esto?

Ejemplo: Mi caso de uso es algo como esto, en la vista de la outer-directive :

<div ng-repeat="e in element"> <inner-directive two-way-attr="e.value"></inner-directive> </div>

Pero inner-directive está en el mismo módulo que outer-directive . No necesita ser encapsulado con un alcance aislado. De hecho, necesito usar la herencia $scope para otros propósitos, por lo que un alcance aislado no es una opción . Es solo que usar un atributo HTML para establecer esta comunicación bidireccional es extremadamente conveniente.


Yo escribí esto. Lo usas así:

twowaybinder.attach($scope, $attrs.isDeactivated, ''isDeactivated'');

.factory(''twowaybinder'', function ($parse) { function twoWayBind($scope, remote, local){ var remoteSetter = $parse(remote).assign; var localSetter = $parse(local).assign; $scope.$parent.$watch(remote, function (value) { localSetter($scope, value); }); $scope.$watch(local, function (value) { remoteSetter($scope, value); }); } return { attach : twoWayBind }; });

Le dará u verdadero enlace de dos vías de los valores de alcance. Nota No creo que $ scope. $ Parent sea necesario, ya que en un escenario heredado o sin alcance, cualquier expresión debería resolverse en el alcance actual. Solo necesitaría llamar a $ parent en un alcance aislado, en cuyo caso no usaría esto, usaría la configuración del alcance aislado.


puede usar dos directivas si gg es un objeto, entonces "=" apunta a un lugar de la memoria.

angular.module(''mymodule'', []).directive(''a'', function($parse, $modal) { return { restrict : ''A'', scope : { gg : "=" }, require : "b", link : function(scope, element, attrs, bCtrl) { scope.$watch(''gg'',function(gg){ bCtrl.setset(scope.gg); } } } }); angular.module(''mymodule'').directive(''b'', function($parse, $modal) { return { restrict : ''A'', /* * scope : { showWarn : "=" }, */ controller : function($scope) { $scope.bb = {}; this.setset = function(nn) { $scope.bb=nn; }; } });


Demo de trabajo aquí

Es posible tener un alcance no aislado y un alcance aislado en la misma directiva. Es posible que desee hacer esto, por ejemplo, si tiene una combinación de ambas plantillas no aisladas (lo que significa que no deben buscar enlaces a través de la herencia de alcance) y plantillas aisladas (deben buscar enlaces en su propio ámbito solamente) y Ambos están definidos en la misma directiva.

Para configurar tanto el ámbito de aislamiento como el no aislado, puede hacer lo siguiente:

  1. En la definición de su directiva, especifique scope=true
  2. En su función de enlace, compile y vincule su plantilla con el parámetro de alcance. Al hacer esto, los enlaces se evalúan en relación con el ámbito no aislado (lo que significa que resuelve los enlaces a través de la herencia de ámbito prototípico).

    link: function(scope, element, attr) { // this template should look for ''model'' using scope inheritance var template2 = angular.element(''<div> Prototypical Scope: {{ model }}</div>''); // add the template to the DOM element.append(template2); // compile and link the template against the prototypical scope $compile(template2)(scope); }

    La ventaja de la herencia de alcance prototípico es que no tiene que importar explícitamente los enlaces al alcance actual de sus directivas. Mientras se defina en el alcance actual o en cualquier alcance más arriba de la cadena de herencia (hasta el alcance de la raíz), el tiempo de ejecución angular podrá resolverlo.

  3. En la misma función de enlace, defina un alcance aislado usando scope.$new(true) . Puede establecer un enlace bidireccional de su modelo importando un modelo a su alcance isolatedScope.model = scope.$eval(attr.model) - isolatedScope.model = scope.$eval(attr.model) :

    link: function(scope, element, attr) { // this template should look for ''model'' in the current isolated scope only var template = angular.element(''<div>Isolate Scope: {{model}}</div>''); // create an isolate scope var isolatedScope = scope.$new(true); // import the model from the parent scope into your isolated scope. This establishes the two-way binding. isolatedScope.model = scope.$eval(attr.model); // add the template to the DOM element.append(template); // compile and link the template against the isolate scope $compile(template)(isolatedScope); }

    La ventaja del ámbito de aislamiento es que todos los enlaces que existen (es decir, están dentro del ámbito) son los que se importan explícitamente. Compare esto con el alcance no aislado, donde los enlaces no necesitan definirse explícitamente en el alcance actual, se podría heredar de cualquier alcance más arriba en la cadena.