2

简化的代码:观察工厂可变

var myApp = angular.module("myApp", []); 
 

 
myApp.factory("mySrvc", function($window) { 
 
    var win = angular.element($window); 
 
    var foo = { 
 
    bar: 0 
 
    }; 
 
    
 
    win.bind("click", function(){ 
 
    foo.bar = foo.bar + 1; 
 
    alert("triggered! foo.bar="+foo.bar); 
 
    }); 
 
    
 
    return { 
 
    foo: foo, 
 
    update: function() { 
 
     foo.bar = foo.bar + 1 
 
    } 
 
    }; 
 
}); 
 

 
myApp.controller("myCtrl", function(mySrvc) { 
 
    this.foo = mySrvc.foo; 
 
    mySrvc.update(); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<html> 
 
    <body ng-app="myApp"> 
 
    <div ng-controller="myCtrl as ctrl"> 
 
     {{ctrl.foo.bar}} 
 
    </div> 
 
    </body> 
 
</html>

现在,当我运行应用程序,在控制器更新foo.bar成功地1所述更新触发而从观察者的{ {}}模型相应地更新html。但是它通过点击鼠标来更新工厂本身,它与更新函数完全相同,但更改不会出现在HTML中。
任何在控制器中使用附加范围的尝试都不成功。 为什么是这样,我如何观察变化?

+2

'.bind( “点击”,...'不会导致消化周期 - 你需要将它包装在'$ rootScope $ apply(function(){...})' –

+0

@PankajParkar,是的......但是,在这种情况下,他正在处理一个全局'$ window',所以它可能就OK了。你这样做吗?其实,是'窗口'技术上考虑的DOM?:) –

+0

@NewDev对不起,我以前的评论老兄..但只是currious知道为什么它应该在服务不是在指令.. –

回答

2

由于@NewDev建议你可以使用$rootScope.$apply,或者你可以通过添加$timeout来间接做到这一点,它会为你启动摘要循环。

代码

win.bind("click", function() { 
    $timeout(function() { 
     foo.bar = foo.bar + 1; 
     alert("triggered! foo.bar=" + foo.bar); 
    }); 
}); 

Working Plunkr

+0

它似乎在做这项工作。你能说一下这个表演吗? $ timeout基本上每秒调用60次可以吗? – Miiller

+0

@Miller是的,你必须..如果你想更新范围变量的绑定..我不会影响性能,如果它只有一个在.. .. –