我有一个js类处理一些逻辑,并试图在角度使用它,所以它可以自动更新当值更改不起作用时,只有当我使用角度函数工作时,引用是可以的,但我确定需要当阵列外部变化时,我需要它来监听角度。 谢谢!
//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;按钮阵列会立即显示和更新。
答案 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();
};
}
答案 1 :(得分:1)
正如@dfsq指出的那样,使用$apply
有效。
或者您可以使用角度版ng-click
而不是onclick
。 ng-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;
答案 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附加到作用域。
这是这个例子的工作小提琴......