Перед тем, как обещание будет разрешено, выдается директива
У меня возникают проблемы с получением моей директивы для предоставления ее содержимого только после того, как мое обещание будет разрешено. Я думал, что 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);
Сфера возвращается в порядке, и когда я проверяю ее в dev-инструментах, scope.product
не undefined, тем не менее, я предполагаю, что, поскольку я проверяю, что обещание было разрешено?
console.log(scope.product)
, однако, возвращает undefined..
Ответы
Ответ 1
Поскольку ваше значение асинхронно заполнено, вам нужно добавить функцию часов, которая обновляет связанный элемент.
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
Как указано в официальном сообщении об этой проблеме (быстро закрывается как "не будет исправлено, потому что это заставит директивы ждать" ), обходным путем является директива в ng-if
:
<div ng-if="myPromiseParam">
<my-directive param="myPromiseParam">
</div>
Ответ 3
Я знаю, что это более старый вопрос, но я подумал, что попробую помочь в предоставлении обновленного ответа.
При использовании маршрутизатора как ui-router, так и ngRouter имеют методы устранения, которые будут разрешать promises при изменении URL-адреса до перехода на этот маршрут и отображения объектов на странице.
ngRouter Разрешить учебник
ui-router Разрешить документы
Другим вариантом вместо использования $watch
является использование углов $q
библиотека обещаний.
Более конкретно, метод $q.when()
. Это принимает значение promises и значения. ЕСЛИ это обещание, что оно сработает .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>
Ответ 4
используйте $watch для своей переменной в своей директиве, чтобы получить обновленное значение вашей переменной.
вы также можете использовать $q для решения обещания.