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是的,你必須..如果你想更新範圍變量的綁定..我不會影響性能,如果它只有一個在.. .. –