在我的承诺得到解决后,我的指令只有在呈现其内容时才会出现问题。我认为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)
然而,返回undefined ..
答案 0 :(得分:81)
如an official thread about this issue中所述(快速关闭为“因为它会使指令等待而无法修复”),解决方法是将指令包装在ng-if
中:
<div ng-if="myPromiseParam">
<my-directive param="myPromiseParam">
</div>
答案 1 :(得分:43)
因为您的值是异步填充的,所以您需要添加一个更新绑定元素的监视功能。
link: function(scope, el, attrs) {
scope.$watch('product', function(newVal) {
if(newVal) { el.text(scope.product.name);}
}, true);
}
您还可以将大量复杂性转移到指令控制器中,并使用链接函数来操作DOM。
true
$watch
的第三个参数会导致深度监视,因为您将此指令绑定到模型。
以下是一些有很好例子的链接:
http://www.ng-newsletter.com/posts/directives.html
http://seanhess.github.io/2013/10/14/angularjs-directive-design.html
答案 2 :(得分:24)
我知道这是一个较老的问题,但我想我会尽力提供更新的答案。
使用路由器时,ui-router和ngRouter都有解析方法,可以在切换到该路由并在页面上呈现内容之前解决URL更改的承诺。
ngRouter Resolve tutorial
ui-router Resolve docs
另一种选择,而不是使用$watch
是使用角度$q
promise library。
更具体地说,$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>
答案 3 :(得分:0)
在指令中对变量使用$ watch以获取变量的更新值。
您也可以使用$ q来解决承诺。