2012-09-19 16 views
5

Los atributos de la directiva no cambian cuando se actualiza el alcance, aún conservan el valor inicial. ¿Que me estoy perdiendo aqui?directivas dinámicas en angularjs

HTML

<ul class="nav nav-pills nav-stacked" navlist> 
    <navelem href="#!/notworking/{{foo}}"></navelem> 
    <navelem href="#!/working">works great</navelem> 
</ul> 

<p>works: {{foo}}</p> 

Javascript (basado en el ejemplo pestañas angular sobre la primera página)

angular.module('myApp.directives', []). 
directive('navlist', function() { 
    return { 
     scope: {}, 
     controller: function ($scope) { 
      var panes = $scope.panes = []; 

      this.select = function(pane) { 
       angular.forEach(panes, function(pane) { 
        pane.selected = false; 
       }); 
       pane.selected = true; 
      } 

      this.addPane = function(pane) { 
       if (panes.length == 0) 
        this.select(pane); 
       panes.push(pane); 
      } 

     } 
    } 
}). 
directive('navelem', function() { 
    return { 
     require: '^navlist', 
     restrict: 'E', 
     replace: true, 
     transclude: true, 
     scope: { href: '@href' }, 
     link: function(scope, element, attrs, tabsCtrl) { 
      tabsCtrl.addPane(scope); 
      scope.select = tabsCtrl.select; 
     }, 
     template: 
      '<li ng-class="{active: selected}" ng-click="select(this)"><a href="{{href}}" ng-transclude></a></li>' 
    }; 
}); 

Respuesta

8

Al definir scope: {} en su directiva, se está creando un isolated scope. Entonces, el alcance principal ahora es invisible desde la directiva.

Si desea remitir el ámbito primario, puede poner scope: true para el alcance compartido (entre las mismas directivas) y omitir la declaración del alcance para el anidamiento del alcance normal. O si solo quiere referirnos al $scope.foo de la matriz, puede definir variables de ámbito explícitas como lo hizo en la directiva hija.

8

Hay tres tipos de herencia alcance Directiva:

  1. n 'alcance: ...' o explícita scope: false - no se crea un nuevo ámbito. La directiva usa el mismo alcance que el padre. Esto es simple y conveniente, pero si está compilando componentes reutilizables, esto no es recomendable, ya que la directiva probablemente solo será utilizable si el alcance padre tiene definidas ciertas propiedades de alcance que la directiva necesita usar/acceder.
  2. scope: true - crea un nuevo ámbito, compartido por todas las directivas en el mismo elemento, con la herencia prototípica normal del ámbito principal. Una vez más, probablemente no sea la mejor opción para los componentes reutilizables, ya que la directiva probablemente no debería tener acceso a las propiedades del alcance principal: podría cambiar accidentalmente algo en el elemento primario.
  3. scope: { ... } - crea un nuevo ámbito "aislado": no hereda de manera prototípica del ámbito primario. Sin embargo, el hash del objeto (es decir, el {...}) nos permite definir las propiedades del alcance de la directiva local que se derivan del alcance principal, por lo que podemos controlar qué propiedades se comparten y cómo.
    1. Use '=' para un potente enlace bidireccional entre una propiedad de ámbito principal y una propiedad de ámbito de directiva: los cambios en cualquiera de las propiedades de ámbito afectan al otro.
    2. Use '@' para vincular el valor de atributo de un padre a una propiedad del alcance de la directiva. Esto es esencialmente unidireccional. Solo los cambios en el alcance principal afectan el alcance de la directiva.
    3. Use '&' para enlazar a las expresiones/funciones del ámbito principal.

para su problema particular, es necesario indicar en el hash objeto que propiedades del ámbito que desea tener de 2 vías de unión.

Para más información sobre los alcances de la directiva (incluyendo fotos), por favor consulte la sección directivas aquí: What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

+0

Esto tal vez la mejor explicación de los alcances directiva que he leído. Gracias. – user2734679

0

igual que Mark Rajcok dijo - Alcance: {} creará un nuevo ámbito aislado que no heredan propiedades de los padres Sin embargo, aún podemos obtener acceso a estas propiedades mediante el uso de la propiedad $ parent.

controlador:

app.controller('indexController', function($scope) { 
    $scope.test="Hello world!"; 
}); 

Directiva

app.directive("test", function() { 
    return{ 
     restrict: "A", 
     scope: {}, 
     controller: function($scope){ 
      console.log("directiv $scope.$parent.test: " + $scope.$parent.test); 
      console.log("directiv $scope.test: " + $scope.test); 
     } 
    }; 
}); 

de salida:

directiv $scope.$parent.test: Hello world! 
directiv $scope.test: undefined