2013-03-08 6 views
11

Позвольте мне начать с того, что то, что я пытаюсь сделать, вероятно, не считается хорошей практикой. Однако мне нужно сделать что-то подобное, чтобы переносить большое веб-приложение в AngularJs небольшими шагами.Угловая: Можно ли просмотреть глобальную переменную (I.e вне области видимости)?

Я пытался делать

$scope.$watch(function() { return myVar; }, function (n, old) { 
        alert(n + ' ' + old); 
       }); 

Где MYVAR является глобальной переменной (определяется в окне)

, а затем изменить MYVAR из консоли. Но он срабатывает только при первой настройке наблюдателя.

Это работает, если я обновлю MYVAR внутри контроллера (см http://jsfiddle.net/rasmusvhansen/vsDXz/3/, но если она обновляется из некоторого наследия Javascript

Есть ли способ для достижения этой цели?

Update Мне нравится Ответ Андерса, если устаревший код полностью отключен, однако в настоящий момент я рассматриваю такой подход, который, как представляется, работает и не включает таймер, срабатывающий каждую секунду:

// In legacy code when changing stuff  
$('.angular-component').each(function() { 
     $(this).scope().$broadcast('changed'); 
}); 

// In angular 
$scope.$on('changed', function() { 
    $scope.reactToChange(); 
}); 

Я награждаю очки Андерсу, хотя я пойду с другим решением, так как его решение правильно решает проблему.

+0

вероятно не хотите использовать 'each' для трансляции так угловом только делает один digest – charlietfl

+1

В вашем примере кода, на что указывает '.angular-component'? – mlhDev

+0

В моем случае я выбрал элемент, который я действительно хотел изменить (с помощью 'angular.element (document.getElementById())', потому что я не использовал jQuery), а затем называл 'scope(). $ Broadcast ('customEventName'); '. Обратите внимание, что мне пришлось использовать '$ apply()' внутри функции '$ on ('customEventName')', чтобы вызвать вызов наблюдателей. –

ответ

12

Проблема здесь, вероятно, в том, что вы изменяете myVar из-за пределов Углового мира. Угловой не работает все циклы циклов/грязных проверок, только когда что-то происходит в приложении, которое должно вызвать дайджест, например, события DOM, о которых знает Угловой. Поэтому, даже если myVar изменился, Angular не видит причин для начала нового цикла дайджеста, поскольку ничего не произошло (по крайней мере, об этом Angular знает).

Для того, чтобы стрелять из ваших часов, вам нужно заставить Angular запустить дайджест, когда вы меняете myVar. Но это было бы немного громоздким, я думаю, вы бы лучше не создавать глобальный наблюдаемый объект, что-то вроде этого:

<!doctype html> 
<html ng-app="myApp"> 
<head> 
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
    <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script> 
    <script> 
    // Outside of Angular 
    window.myVar = {prop: "value1"}; 
    var myVarWatch = (function() { 
     var watches = {}; 

     return { 
      watch: function(callback) { 
       var id = Math.random().toString(); 
       watches[id] = callback; 

       // Return a function that removes the listener 
       return function() { 
        watches[id] = null; 
        delete watches[id]; 
       } 
      }, 
      trigger: function() { 
       for (var k in watches) { 
        watches[k](window.myVar); 
       } 
      } 
     } 
    })(); 

    setTimeout(function() { 
     window.myVar.prop = "new value"; 
     myVarWatch.trigger(); 
    }, 1000); 

    // Inside of Angular 
    angular.module('myApp', []).controller('Ctrl', function($scope) { 
     var unbind = myVarWatch.watch(function(newVal) { 
      console.log("the value changed!", newVal); 
     }); 

     // Unbind the listener when the scope is destroyed 
     $scope.$on('$destroy', unbind); 
    }); 
    </script> 
</head> 
<body ng-controller="Ctrl"> 

</body> 
</html> 
+1

Спасибо за вход Anders, я думаю, что это очень удобный способ сделать это, если нет способа изменить устаревший код. Я могу внести небольшие изменения в устаревший код, поэтому я думаю, что у меня другой подход (см. Мое обновление). – rasmusvhansen

+1

Btw, проверьте 'Object.observe()'. Он позволяет следить за изменениями на объекте. Он по-прежнему не реализован во многих браузерах, но для него есть полисы. –

+0

Мне нужно было использовать $ scope. $ Применять внутри углового myVarWatch.watch, чтобы иметь угловой дайджест изменений. – willJk

Смежные вопросы