Estoy teniendo problemas para conseguir mi directiva para representar su contenido sólo después de que mi promesa se ha resuelto. Pensé then() se supone que para hacer esto, pero parece ser que no funciona..

Aquí está mi controlador:

//Generated by CoffeeScript 1.6.3
(function() {
  var sprangularControllers;

  sprangularControllers = angular.module('sprangularControllers', ['sprangularServices', 'ngRoute']);

  sprangularControllers.controller('productsController', [
    '$scope', '$route', '$routeParams', 'Product', 'Taxonomy', function($scope, $route, $routeParams, Product, Taxonomy) {
      Taxonomy.taxonomies_with_meta().$promise.then(function(response) {
        return $scope.taxonomies = response.taxonomies;
      });
      return Product.find($routeParams.id).$promise.then(function(response) {
        return $scope.currentProduct = response;
      });
    }
  ]);

}).call(this);

Mi directiva:

//Generated by CoffeeScript 1.6.3
(function() {
  var sprangularDirectives;

  sprangularDirectives = angular.module('sprangularDirectives', []);

  sprangularDirectives.directive('productDirective', function() {
    return {
      scope: {
        product: '='
      },
      templateUrl: 'partials/product/_product.html',
      link: function(scope, el, attrs) {
        console.log(scope);
        console.log(scope.product);
        return el.text(scope.product.name);
      }
    };
  });

}).call(this);

Ámbito devuelve bien, y cuando me registre en dev tools scope.product no es indefinido sin embargo, estoy asumiendo que es porque por el momento puedo comprobar que la promesa ha sido resuelto?

console.log(scope.product) sin embargo, devuelve undefined..

4 Comentarios

  1. 43

    Porque su valor es de forma asincrónica poblada, es posible que desee agregar una función de reloj que las actualizaciones de sus elementos enlazados.

      link: function(scope, el, attrs) {
        scope.$watch('product', function(newVal) {
            if(newVal) { el.text(scope.product.name);}
        }, true);
      }

    También se puede mover una gran cantidad de complejidad en una directiva de la controladora y el uso de la función de enlace para manipular el DOM sólo.

    La true tercer parámetro a $watch hace una observación en profundidad, ya que estamos de unión de la presente directiva a un modelo.

    Aquí hay un par de enlaces con buenos ejemplos:

    http://www.ng-newsletter.com/posts/directives.html

    http://seanhess.github.io/2013/10/14/angularjs-directive-design.html

    • Gracias Jim, ¿eso quiere decir que simplemente aislar el ámbito de aplicación que no se actualiza? El uso de un reloj hizo cruzar mi mente, pero yo no vea los ejemplos en línea, así que supuse que no era el ‘angular camino» …con la esperanza de que no es el caso, va a dar a este un ir y el informe de nuevo.
    • No entiendo tu pregunta. Las directivas son sólo anidada dentro de los ámbitos de su controlador de su ámbito de aplicación. Si no se define explícitamente un ámbito, angular crea uno. También crea relojes para usted en el fondo (como cuando haces {{project.name}}), así que yo diría que el reloj es el más angular manera. También, Dominar Desarrollo de una Aplicación Web con AngularJS | Packt Publishing es un buen libro.
    • Si alguien viene por el este. Que $ver también podría estar en el controlador principal así. Ya que la directiva está enlazado a la misma alcance el valor. También si usted tiene un reloj en un objeto que se presenta un objeto nuevo punto anotadas valor, a continuación, usted debe comprobar si existe en el reloj así.
  2. 81

    Como se indica en un oficial hilo sobre este tema (rápidamente cerrado como «no va a arreglar porque podría hacer que las directivas de espera»), una solución es para envolver a su directiva en un ng-if :

    <div ng-if="myPromiseParam">
      <my-directive param="myPromiseParam">
    </div>
    • Ahhh sooo mucho más fáciles de solucionar el problema
    • Por el bien de rendimiento, no olvides usar bind-una vez sintaxis (ng-if=»::myPromiseParam») si usted sabe que no va a cambiar.
    • Esto debe aceptarse en lugar de utilizar aceptado que el uso de reloj.
  3. 24

    Sé que esta es una antigua pregunta, pero pensé que iba a probar mi mano en proporcionar una respuesta actualizada.

    Cuando se utiliza un router, tanto de la interfaz de usuario del router y ngRouter han resolver métodos que va a resolver sus promesas en la url de cambios antes de cambiar a la ruta y la representación de las cosas en la página.

    ngRouter Resolver tutorial

    la interfaz de usuario del router Resolver docs

    Otra opción, en lugar de utilizar $watch es el uso de angulars $p promesa de la biblioteca.
    Más específicamente, el $q.when() método. Esta toma de promesas y valores. SI es una promesa que se va a disparar un .then() cuando la promesa se resuelve. Si es un valor, que se envuelve en una promesa y de inmediato lo resuelve.

    link: function(scope, el, attrs){
        $q.when(scope.product).then(function(product){
            scope.product = product;
            el.text(scope.product.name);
        });
    }

    O hay un par de manera que usted puede no mostrar nada solo con html.

    <product-directive product='object'>
        <!-- Will hide span until product.name exists -->
        <span ng-show='product.name'>{{ product.name }}</span> 
    
        <!-- Will show default text until key exists -->
        {{ product.name || 'Nothing to see here' }}
    
        <!-- Will show nothing until key exists -->
        <span ng-bind='product.name'></span>
    </product-directive>    
  4. 0

    uso $ver en su variable en la directiva para obtener el valor actualizado de la variable.

    usted también puede hacer uso de la $q para resolver la promesa.

Dejar respuesta

Please enter your comment!
Please enter your name here