当前位置: 首页 > 面试题库 >

Angular:是否可以监视全局变量(即在范围之外)?

艾仲渊
2023-03-14
问题内容

首先,我想说我想做的事情可能不被认为是好的做法。但是,我需要执行类似的操作,以便以较小的增量步骤将大型Web应用程序迁移到AngularJs。

我试着做

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

其中myVar是全局变量(在窗口上定义)

然后从控制台更改myVar。但是只有在首次设置观察者时才会触发。

如果我从控制器内部更新myVar(请参阅http://jsfiddle.net/rasmusvhansen/vsDXz/3/),则该方法有效,但如果它是从某些旧版javascript更新的,则无效

有什么办法可以做到这一点?

更新 如果遗留代码完全超出限制,我喜欢Anders的回答。但是,目前,我正在研究这种方法,该方法似乎有效,并且不包括每秒触发一次的计时器:

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

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

尽管我将使用其他解决方案,但我仍在向Anders奖励积分,因为他的解决方案可以正确解决所述问题。


问题答案:

这里的问题可能是您是myVar从Angular世界之外进行修改的。Angular不会一直运行摘要周期/脏检查,只有当应触发摘要的应用程序中发生某些事情时,例如Angular知道的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>


 类似资料:
  • 问题内容: 给定以下代码: 因为函数变量中的代码在外部范围内,但不在全局范围内。是否可以在函数内修改变量?我当然可以从和阅读,但是如何修改? 问题答案: Python 3.x具有关键字。我认为这可以满足您的要求,但是我不确定您是在运行python 2还是3。 非本地语句使列出的标识符引用最近的封闭范围中的先前绑定的变量。这很重要,因为绑定的默认行为是首先搜索本地名称空间。该语句允许封装的代码在全局

  • 问题内容: 我需要从指令中的父控制器继承范围。我不一定要离开范围:false。我也不一定要使用孤立的作用域,因为要获得我确实关心的值正确链接(需要在父控制器中考虑很多值),就需要大量的工作。 如果要更新父范围,在我的指令中使用是否有意义? 请检查小提琴 问题答案: 尽管@user1737909已经引用了SO问题来阅读(AngularJS中范围原型/原型继承的细微差别是什么?它将解释该问题并建议各种

  • 问题内容: 如何在Python中的函数中声明全局变量? 也就是说,因此不必在之前声明它,而是可以在函数外部使用它。 问题答案: 是的,但是为什么?

  • 问题内容: 我正在写指令,并且需要注意父作用域的更改。不知道我是否正在按照首选方式执行此操作,但是它不能与以下代码一起使用: 它记录了窗口加载,但是即使更改了overlaytype,也不会再次登录。 我怎样看待变化? 编辑:这是整个指令。不确定我为什么要使用儿童镜 问题答案: 您应该在子作用域上具有 data 属性,作用域在父作用域和子作用域之间使用原型继承。 同样, $ watch 方法期望的第

  • 本章介绍当模板在访问变量时发生了什么事情,还有变量是如何存储的。 当调用 Template.process 方法时,它会在方法内部创建一个 Environment 对象,在 process 返回之前一直使用。 该对象存储模板执行时的运行状态信息。除了这些,它还存储由模板中指令,如 assign, macro, local 或 global 创建的变量。 它不会尝试修改传递给 process 的数据

  • 问题内容: 是否可以动态更改全局样式表? 编辑:目的是允许用户选择他喜欢的样式。 在Angular 1中,我能够将控制器包装在head标签周围并在其中使用绑定。 下面的示例(简化代码): index.html AppController 在Angular 2中有可能吗? 问题答案: 我最终使用了Igor在这里提到的DOCUMENT令牌。 从那里,我可以将href换成样式。 HTML: TS: