2014-09-26 66 views
0

我有一个问题,我有一个暴露字符串的服务。这个服务有一个函数来更新字符串的值。该服务内部知道该值已更改,但是,从外部看,该值从不更新。AngularJS - 暴露字符串的服务

如果我将字符串嵌套在对象中,那么它都可以工作,但我并不想嵌套它。

任何人都可以解释为什么发生这种情况?这感觉就像它应该工作,感觉就像我缺少一些基本的东西。

服务:

myApp.service('neverChanges', function() { 
    var id = 'Hello'; 
    var changeId = function() { 
     console.log('pre change:' + id); 
     id = 'World'; 
     console.log('post change:' + id); 
    }; 

    return { 
     id: id, 
     changeId: changeId 
    }; 
}); 

控制器:

myApp.controller('Controller1', ['neverChanges', function (neverChanges) { 
    this.idValue = function() { 
     return neverChanges.id; 
    } 
    this.clickHandler = function() { 
     console.log('Trust me, I did fire...'); 
     neverChanges.changeId(); 
     console.log('external post change:' + neverChanges.id); 
    }; 
}]); 

标记:

<div ng-app="myApp"> 
    <div ng-controller="Controller1 as vm"> 
     <h3>This will never change:</h3> 
     <button ng-click="vm.clickHandler()">Click Me!</button> 
     <p>Values:</p> 
     <p>id: {{vm.idValue()}}</p> 
</div> 

小提琴显示了两种方案:http://jsfiddle.net/KyleMuir/2nhoc2rz/

+0

小心解释downvote? – 2014-09-26 21:26:18

回答

3

的问题是,你有局部变量ID :var id = 'Hello';

在你这个局部变量的值复制到目标函数以后,你回:

return { 
     id: id, 
     changeId: changeId 
    }; 

所以从这里返回的对象有一个属性格式id这是你原来的id变量的副本,你changeId函数只是改变你的本地变量,但当然不是副本。

为了防止您需要保留对您返回的对象的引用。那可以例如是这样的:

var result = {id:'Hello'}; 
result.changeId = function() { 
    console.log('pre change:' + result.id); 
    result.id = 'World'; 
    console.log('post change:' + result.id); 
}; 
return result; 

参见工作版本:http://jsfiddle.net/y4mxazqh/

这样你摆脱局部变量的id,你可以改变你返回的对象。

当然return也会创建一个对本地变量result的引用的副本。但是既然返回的引用和局部变量都指向同一个对象,你可以改变那个对象的内容,然后这两个引用仍然引用一个id已经改变的对象。

编辑:

本质originof的回答解决了不同的方法同样的问题:因为你调用vm.clickHandler()功能clickHandler()得到this设置为反过来vmvm是你返回的对象。因此你可以访问返回的对象。但请注意,如果您执行如下代码:

var func = vm.clickHandler(); 
func(); 

这不会是一样的。在这种情况下,this不会被设置为vm,并且您已丢失。当您选择基于this的解决方案时,您应该了解这种情况。

+0

感谢您对基于'this'的解决方案背后的解释。在我的情况下,这实际上很好,因为这是我将使用它的唯一方法。 – 2014-09-26 21:36:24

4

你必须使用这个

var changeId = function() { 
    console.log('pre change:' + id); 
    this.id = 'World'; 
    console.log('post change:' + id); 
}; 
+0

该死的,我知道我错过了一些简单的东西。谢谢。 – 2014-09-26 21:25:58

1

您传递另一个对象和功能范围功能改变 尝试:的

this.id = "World" 

代替

id = "World"