Часы Angularjs не срабатывают

0

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

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

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

MySvc.loaded = true;

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

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

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

  • 2
    Во-первых, странно, что сервис имеет доступ к $scope . Можете ли вы опубликовать полный исходный код для этой ситуации? Возможно, ваши директивы имеют собственную область видимости, и поэтому loaded свойство в контроллере не такое, как в областях действия директив. Попробуйте использовать $scope.$broadcast вместо флагов bool для уведомления ваших директив, что все готово.
  • 0
    Вы пытались использовать $scope.$apply после изменения значения на true ?
Показать ещё 2 комментария
Теги:
listener
angularjs-directive
angularjs-service

3 ответа

1
Лучший ответ

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

$scope.data = MySvc.data;

И добавьте к этому, например 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!!"

См. Это в действии (CoffeeScript, поскольку он быстрее для прототипирования, но должен быть достаточно ясным).

  • 0
    Ваш комментарий побудил меня понять, что происходит не так. Я привык так поступать с объектами, а не с простыми базовыми типами данных. Когда я делаю это с объектами, я передаю значение указателя на объект. С простым типом данных он только передает значение. У меня была проблема с трансляциями, занимающими исключительно много времени, но ваш комментарий помог мне понять ответ, который я опубликую позже, как только у меня все получится.
  • 0
    Что бы вы ни выбрали, невозможно, чтобы $watch работал быстрее, чем $broadcast . $watch оценивается в каждом цикле дайджеста.
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);
   });
 });

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню