Подтвердить что ты не робот

Angular: Можно ли просмотреть глобальную переменную (I.e вне области видимости)?

Позвольте мне начать с того, что то, что я пытаюсь сделать, вероятно, не считается хорошей практикой. Тем не менее, мне нужно сделать что-то подобное, чтобы переносить большое веб-приложение в AngularJs небольшими шагами.

Я пробовал делать

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

Где myVar - глобальная переменная (определенная в окне)

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

Он работает, если я обновляю myVar из контроллера (см. http://jsfiddle.net/rasmusvhansen/vsDXz/3/, но не если он обновлен из некоторого устаревшего javascript

Есть ли способ достичь этого?

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

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

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

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

4b9b3361

Ответ 1

Проблема здесь, вероятно, в том, что вы изменяете myVar извне мира Angular. Angular не запускает циклы дайджестов/грязные проверки все время, только когда что-то происходит в приложении, которое должно запускать дайджест, например, события DOM, о которых знает Angular. Таким образом, даже если 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>