У меня есть три элемента для этой программы. Во-первых, на службе у меня есть:
$scope.loaded = MySvc.loaded;
$scope.loaded = false;
Затем, в контроллере, который импортирует эту услугу, у меня есть ряд вводных вещей. Мне нужно инициировать события в директивах, как только контроллер будет выполнен с его асинхронной работой, поэтому в контроллере, когда этот триггер готов, я делаю
MySvc.loaded = true;
И затем в директиве, которая также импортирует сервис, у меня есть,
$scope.loaded = MySvc.loaded;
$scope.$watch('loaded', function (newValue, oldValue) {
Триггеры директивы при loaded
инициализируются значением "false", но когда я меняю значение на "true", ничего не происходит. Часы просто не срабатывают. Почему нет? Как это исправить?
Это прекрасный способ сделать что-то, и я рассматриваю его как ортогональное к обещаниям (которые действительно чрезвычайно полезны). Ваша проблема связана с нарушением связи, которую вы создали с заданием. Вместо этого попробуйте:
$scope.data = MySvc.data;
И добавьте к этому, например MySvc.data.loaded = false
. Таким образом, переменная data
никогда не переназначается, поэтому ваша связь между контроллером и сервисом остается неизменной.
Затем вы можете смотреть данные. data.loaded
или просматривать data
в виде коллекции, передавая true как 3-й вариант в $watch
.
Как я уже сказал в комментарии, у вас могут быть проблемы с вашими областями, переопределяющими loaded
свойство.
Попробуйте использовать угловые события, чтобы решить вашу проблему.
angular.module('test', [])
.controller 'MyController', ($scope, $timeout) ->
$timeout ->
$scope.$broadcast('READY')
, 2000
.directive 'myDirective', ->
scope: {}
template: '<span>{{ value }}</span>'
link: ($scope) ->
$scope.value = "I'm waiting to be ready..."
$scope.$on 'READY', ->
$scope.value = "I'm ready!!"
См. Это в действии (CoffeeScript, поскольку он быстрее для прототипирования, но должен быть достаточно ясным).
$watch
работал быстрее, чем $broadcast
. $watch
оценивается в каждом цикле дайджеста.
Вы делаете это сложнее. Вместо этого используйте обещания !!! Они милые. Обещания сохраняют свое разрешение.
.factory('hello_world', function ($q, $timeout) {
var promise = $q.defer;
$timeout(function () {
promise.resolve('hello world');
}, 1000)
return promise.promise;
})
.controller('ctrl', function ($scope, hello_world) {
hello_world.then(function (response) {
console.log("I will only be ran when the async event resolves!");
console.log(response);
});
});
Как вы видите, обещания намного лучше, без часов. Нет странных ворот. Упрощенный и сексуальный. ;)
$scope
. Можете ли вы опубликовать полный исходный код для этой ситуации? Возможно, ваши директивы имеют собственную область видимости, и поэтомуloaded
свойство в контроллере не такое, как в областях действия директив. Попробуйте использовать$scope.$broadcast
вместо флагов bool для уведомления ваших директив, что все готово.$scope.$apply
после изменения значения наtrue
?