3

我有两个控制器和一个共享服务。第一个控制器呈现一些文本。其他控制器有一个按钮,必须更改第一个控制器范围并重新呈现文本(具有新值)

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 留意变化?

4

1 回答 1

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 支持闭包,这很容易。

于 2013-06-16T13:20:49.203 回答