在承诺解决之前,正在制定指令

Mel*_*991 59 javascript angularjs angularjs-directive

我的指令只有在我的承诺得到解决后才能呈现其内容,我遇到了问题.我以为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);
Run Code Online (Sandbox Code Playgroud)

我的指示:

// 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);
Run Code Online (Sandbox Code Playgroud)

范围返回没关系,当我在开发工具中检查时,工具scope.product并不是未定义的,但我认为这是因为当我检查它时,承诺已经解决了?

console.log(scope.product) 但是,返回undefined ..

Jav*_*ome 81

正如关于这个问题的官方帖子中所说的那样(快速关闭为"因为它会使指令等待而不会修复"),解决方法是将指令包装在ng-if:

<div ng-if="myPromiseParam">
  <my-directive param="myPromiseParam">
</div>
Run Code Online (Sandbox Code Playgroud)

  • 啊,太容易解决问题了 (5认同)
  • 为了提高性能,如果您知道它不会改变,请不要忘记使用bind-once语法(ng-if =":: myPromiseParam"). (4认同)
  • 这应该被接受而不是使用被接受的使用手表的人. (2认同)

Jim*_*ert 43

因为您的值是异步填充的,所以您需要添加一个更新绑定元素的监视功能.

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

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

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

以下是一些有很好例子的链接:
http://www.ng-newsletter.com/posts/directives.html
http://seanhess.github.io/2013/10/14/angularjs-directive-design.html


mig*_*k35 24

我知道这是一个较老的问题,但我想我会尽力提供更新的答案.

使用路由器时,ui-router和ngRouter都有解析方法,可以在切换到该路由并在页面上呈现内容之前解决URL更改的承诺.

ngRouter解析教程
ui-router解析文档

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

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

或者有几种方法你不能用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>    
Run Code Online (Sandbox Code Playgroud)