为什么外部更新的阵列不会自动刷新?

时间:2014-12-05 19:07:29

标签: javascript angularjs class

我有一个js类处理一些逻辑,并试图在角度使用它,所以它可以自动更新当值更改不起作用时,只有当我使用角度函数工作时,引用是可以的,但我确定需要当阵列外部变化时,我需要它来监听角度。 谢谢!

http://jsfiddle.net/9k2zw1ar/

//create class exposed to window
(function(w){

    var Foo=function(){
        this.add=function(){
            Foo.arr.push('js-'+(Math.random() * 100));
        }
    }
    Foo.arr=['a','b','c'];
    w.Foo=Foo;
})(window);
//instantiate one class , used in button
var foo=new Foo;
//angular app
var App= angular.module('App',[]);
//add array reference using "Value" 
App.value('arr',Foo.arr);
//angular controller
App.controller('ClientController', ['$scope','arr', function($scope,arr) {
  $scope.markers = arr;
  $scope.add=function(){
    arr.push('ng-'+(Math.random() * 100));
  };
}]);

这是html代码

<div ng-app="App" >

<div ng-controller="ClientController">

  <div  ng-repeat='marker in markers'>
              <p> {{marker}}</p>

  </div>
    <button ng-click='add()'>add NG</button>
    <button  onclick="foo.add()">add js</button>
</div>

</div>

问题: 当我用按钮&#34更改数组时,添加JS&#34;它不会自动更新。但是当我按下&#34;添加&#34;按钮阵列会立即显示和更新。

3 个答案:

答案 0 :(得分:5)

问题是,当您从角度应用程序外部更改数组时,它不知道某些内容已更改。通常您需要通知它,因此范围需要更新其观察者。您需要做的就是手动触发摘要循环,例如通过在根作用域上调用$apply方法。

唯一棘手的部分是你需要从外面以某种方式访问​​范围。要访问应用程序的根范围,您需要调用scope元素的angular.element(appRoot)方法。其中appRoot是注册了应用程序的DOM元素(ng-app属性)。例如:

var Foo = function () {
    this.add = function () {
        Foo.arr.push('js-' + (Math.random() * 100));
        this.apply();
    };

    this.apply = function() {
        var appRoot = document.querySelector('[ng-app]');
        angular.element(appRoot).scope().$apply();
    };
}

演示:http://jsfiddle.net/9k2zw1ar/1/

答案 1 :(得分:1)

正如@dfsq指出的那样,使用$apply有效。

或者您可以使用角度版ng-click而不是onclickng-click会自动处理触发摘要周期(https://github.com/angular/angular.js/wiki/When-to-use-%24scope.%24apply%28%29)。

<button ng-click="foo.add()">add js</button>

为了实现这一点,foo需要在您的范围内可见。将此添加到控制器将实现:

$scope.foo = foo;

更新了小提琴:http://jsfiddle.net/kmmuao7u/

答案 2 :(得分:1)

使用您现有的设置,没有任何实质性的重构,它也可以这样工作......

更改此

<button  onclick="foo.add()">add js</button>

到此

<button  ng-click='addJs()'>add js</button>

注意:更改&#39; addJs&#39;到你喜欢的名字

将此行添加到您的控制器

$scope.addJs = foo.add;

Angular将更新&#39; arr&#39;数组都是自己的,因为它已经通过$ scope.markers附加到作用域。

这是这个例子的工作小提琴......

jsfiddle Link