我有两个控制器和一个共享服务。 第一个控制器呈现一些文本。其他Controller有一个按钮,必须更改第一个控制器范围并重新呈现文本(带有新值)
HTML
<div ng-controller="Controller1">
Value is: {{object}}
</div>
<div ng-controller="Controller2">
<button ng-click="changeValue()">Click to change Value</button>
</div>
JS
function Controller1($scope, mainServices) {
$scope.object = mainServices.getValue();
};
function Controller2($scope, mainServices) {
$scope.changeValue = function(){
mainServices.getValue('Hello');
console.log('button is pressed');
};
};
testApp.factory('mainServices', function(){
return {
getValue: function(update) {
var defaultValue = 'Hi';
if( typeof(update)==='undefined') { value = defaultValue; }
else { value = update; }
console.log('should be changed to', update);
return value;
}
}
});
关于Plunker http://plnkr.co/edit/IWBEvAfvLbzJ0UD2IqGB?p=preview
为什么这不起作用?如何告诉Angular注意变化?
答案 0 :(得分:8)
嗯,我认为这不是最好的解决方案,但问题是可能的。 您不必仅仅更改值本身,而是必须在工厂的return语句之前创建一个对象。
var obj = {}
然后你只需更改此对象的属性:
if( typeof(update)==='undefined') { obj.val = defaultValue; }
else { obj.val = update; }
并返回对象:
return obj;
其他控制器可以不受影响,但是你必须更改你的html: 你必须放入
{{object.val}}
为了听取变化。
http://plnkr.co/edit/rjsrkbaQ8QyWGGFI9HYl?p=preview
这很简单:在javascript中,如果你调用一个原始返回值的函数就像一个字符串(是的,字符串可以是javascript中的原语),它只是这个原语的副本,所以用
$scope.object = mainServices.getValue();
您只需将值传递给$ scope.object,该值不受其他getValue()调用的影响 但是如果我们从getValue()返回一个对象,我们会得到对这个对象的引用。因此,如果我们在getValue()中对此引用对象进行更改,则angularjs将能够注意到已更改的对象,因为它在两个控制器中都被跟踪。 因此,我们必须一次又一次地引用同一个对象,但由于javascript支持闭包,这非常简单。