角:是否有可能看一个全局变量(即一个范围之外)? [英] Angular: Is it possible to watch a global variable (I.e outside a scope)?

查看:90
本文介绍了角:是否有可能看一个全局变量(即一个范围之外)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我说什么,我试图做的是可能不是好的做法开始。但是,我需要做这样的事情,以迁移大型Web应用AngularJs在小的增量步。

Let me start by saying that what I am trying to do is probably not considered good practice. However, I need to do something like this in order to migrate a large web app to AngularJs in small incremental steps.

我试图做

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

其中myVar的是一个全局变量(在窗口中定义)

Where myVar is a global variable (defined on window)

然后从控制台改变myVar的。
但是,只有当第一个建立观察者闪光。

And then changing myVar from the console. But it only fires when first setting up the watcher.

如果我从控制器内更新myVar的它的工作原理(见 http://jsfiddle.net/rasmusvhansen/vsDXz/3/ 的,但如果它是从一些遗留更新的JavaScript

It works if I update myVar from within the controller (see http://jsfiddle.net/rasmusvhansen/vsDXz/3/, but not if it is updated from some legacy javascript

有没有办法实现这一目标?

Is there any way to achieve this?

更新
我喜欢Anders的答案,如果传统code是完全关闭的限制。然而,在那一刻我在看这个方法,这似乎工作,不包括定时器触发每一秒:

Update I like Anders' answer if the legacy code is completely off limits. However, at the moment I am looking at this approach which seems to work and does not include a timer firing every second:

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

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

我授予点,安德斯即使我将与另一种解决方案去,因为他的解决方案,正确解决了问题说明。

I am awarding points to Anders even though I will go with another solution, since his solution correctly solves the problem stated.

推荐答案

这里的问题可能是,你从世界角度之外的修改 myVar的。角不运行周期消化/脏检查所有的时间,只有当事情应该引发消化,如角知道DOM事件的应用程序发生。所以,即使 myVar的已经改变,角认为没有理由开始一个新的循环消化,因为一切都没有发生(至少角知道)。

The issue here is probably that you're modifying myVar from outside of the Angular world. Angular doesn't run digest cycles/dirty checks all the time, only when things happen in an application that should trigger a digest, such as DOM events that Angular knows about. So even if myVar has changed, Angular sees no reason to start a new digest cycle, since nothing has happened (at least that Angular knows about).

因此​​,为了激发你的手表,你需要强制角当您更改 myVar的运行摘要。但是,这将是一个有点麻烦,我想你会更好地创建一个全局对象观察到,像这样:

So in order to fire your watch, you need to force Angular to run a digest when you change myVar. But that would be a bit cumbersome, I think you would be better of to create a global observable object, something like this:

<!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>

这篇关于角:是否有可能看一个全局变量(即一个范围之外)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆