AngularJS:如何在另一个控制器中使用触发器更改一个控制器中的范围

时间:2013-06-16 12:48:44

标签: javascript angularjs

我有两个控制器和一个共享服务。 第一个控制器呈现一些文本。其他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注意变化?

1 个答案:

答案 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支持闭包,这非常简单。