0

У меня есть три элемента для этой программы. Во-первых, на службе, у меня есть:Часы Angularjs не запускаются

$scope.loaded = MySvc.loaded; 
$scope.loaded = false; 

Затем в контроллер, который импортирует эту услугу, у меня есть ряд вводных вещей. Мне нужно, чтобы вызвать события в директивах после того, как контроллер делается с asycnhronous работы, так и в контроллере, когда этот триггер готов, я

MySvc.loaded = true; 

И тогда в директиве, которая также импортирует услуги, у меня есть,

$scope.loaded = MySvc.loaded; 
$scope.$watch('loaded', function (newValue, oldValue) { 

директива срабатывает, когда loaded инициализируется «ложь», но когда я изменить значение «истина», ничего не происходит. Часы просто не срабатывают. Почему нет? Как это исправить?

+2

Прежде всего, странно, что служба имеет доступ к '$ scope'. Можете ли вы опубликовать полный исходный код для этой ситуации? Вероятно, ваши директивы имеют свой собственный масштаб, и поэтому свойство 'loaded' в контроллере не совпадает с областью действия директив. Попробуйте использовать '$ scope. $ Broadcast' вместо флагов bool для уведомления ваших директив, все готово. – fracz

+0

Вы пытались использовать '$ scope. $ Apply' после изменения значения на' true'? –

+0

@JamesBrierley Да. Это вызвало ошибку, потому что дайджест уже действовал. –

ответ

1

Это прекрасный способ сделать что-то, и я рассматриваю его как ортогональное к обещаниям (которые действительно чрезвычайно полезны). Ваша проблема связана с нарушением связи, которую вы создали с заданием. Вместо этого попробуйте:

И добавить к этому, например. MySvc.data.loaded = false. Таким образом, переменная data никогда не переназначается, поэтому ваша связь между контроллером и сервисом остается неизменной.

Тогда вы можете либо посмотреть data.loaded, либо посмотреть data в качестве коллекции, передав true, как 3-й вариант, до $watch.

1

Как я уже сказал в комментарии, у вас могут возникнуть проблемы с вашими областями, переопределяющими свойство 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!!" 

See this in action (CoffeeScript, как это быстрее для прототипирования, но должно быть достаточно ясно).

+0

Ваш комментарий побудил меня понять, что происходит не так. Я привык так поступать с объектами ... не с простыми базовыми типами данных. Когда я делаю это с объектами, я передаю значение указателя на объект. С простым типом данных он проходит только по значению.У меня была проблема с трансляциями, занимающими исключительно длительное время, но ваш комментарий помог мне понять ответ, который я выложу позже, как только у меня все получится. –

+0

Что бы вы ни закончили, невозможно, чтобы '$ watch' был быстрее, чем' $ broadcast'. '$ watch' оценивается на каждом цикле дайджеста. – fracz

0

Вы делаете это сложнее. Вместо этого используйте обещания !!! Они милые. Обещания сохраняют свое разрешение.

.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); 
    }); 
}); 

Как вы можете видеть, обещания намного лучше, без часов. Нет странных ворот. Упрощенный и сексуальный. ;)