在解决承诺之前发出指令



我遇到问题,让我的指令只有在我的承诺得到解决后才能呈现其内容。我以为then()应该这样做,但它似乎不起作用。

这是我的控制器:

// 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);

我的指令:

// 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);

范围返回正常,当我在开发工具中检查它时scope.product不是未定义的,但是我假设这是因为当我检查它时,承诺已经解决?

但是,console.log(scope.product)返回未定义。

正如在关于此问题的官方帖子中所述(迅速关闭为"不会修复,因为它会使指令等待"),解决方法是将您的指令包装在ng-if中:

<div ng-if="myPromiseParam">
  <my-directive param="myPromiseParam">
</div>

由于您的值是异步填充的,因此您需要添加一个更新绑定元素的监视函数。

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

您还可以将很多复杂性转移到指令控制器中,并使用链接函数仅操作 DOM。

$watch true第三个参数会导致深度监视,因为您要将此指令绑定到模型。

以下是几个带有良好示例的链接:

http://www.ng-newsletter.com/posts/directives.htmlhttp://seanhess.github.io/2013/10/14/angularjs-directive-design.html

我知道

这是一个较老的问题,但我想我会尝试提供更新的答案。

使用路由器时,ui-router 和 ngRouter 都有 resolve 方法,这些方法将在切换到该路由并在页面上呈现内容之前解析 url 更改的承诺。

ng路由器解析教程
ui-router 解析文档

另一种选择,而不是使用$watch是使用角度$q承诺库。更具体地说,$q.when()方法。这需要承诺和价值观。如果这是一个承诺,它将在承诺解决时触发.then()。如果它是一个值,它会将其包装在一个承诺中并立即解析它。

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

或者有几种方法,你不能只用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>    

指令中的变量上使用$watch来获取变量的更新值。

您还可以利用$q来解决承诺。

最新更新