Директива выносится до того, как обещание будет разрешено
у меня возникли проблемы с получением моей директивы для отображения ее содержания только после того, как мое обещание было решено. Я думал 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 возвращает OK, и когда я проверяю его в dev tools scope.product
не является неопределенным, однако я предполагаю, что это потому, что к тому времени, когда я проверяю его обещание было решили?
console.log(scope.product)
однако, возвращает undefined..
4 ответа:
поскольку ваше значение асинхронно заполняется, вы захотите добавить функцию watch, которая обновляет ваш связанный элемент.
link: function(scope, el, attrs) { scope.$watch('product', function(newVal) { if(newVal) { el.text(scope.product.name);} }, true); }
вы также можете переместить большую сложность в контроллер директив и использовать функцию link для управления только DOM.
The
true
третий параметр$watch
вызывает глубокое наблюдение, так как вы привязываете эту директиву к модели.вот несколько ссылок с хорошим examples:
http://www.ng-newsletter.com/posts/directives.html
http://seanhess.github.io/2013/10/14/angularjs-directive-design.html
Как говорится в официальная тема об этой проблеме (быстро закрывается как "не исправит, потому что это заставит директивы ждать"), обходной путь-обернуть вашу директиву в
ng-if
:<div ng-if="myPromiseParam"> <my-directive param="myPromiseParam"> </div>
Я знаю, что это более старый вопрос, но подумал, что попробую дать обновленный ответ.
при использовании маршрутизатора как ui-router, так и ngRouter имеют методы разрешения, которые будут разрешать обещания при изменении url-адреса перед переключением на этот маршрут и отображением вещей на странице.
ngrouter Resolve tutorial
ui-router Resolve docsдругой вариант, вместо использования
$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>