我有一个问题,我有一个公开字符串的服务。此服务上有一个函数可以更新字符串的值。该服务在内部知道该值已更改,但是,外部值NEVER更新。
如果我将字符串嵌入对象中,那么它一切正常,但我并不想真正嵌套它。
任何人都可以解释为什么会这样吗?感觉它应该工作,感觉我错过了一些基本的东西。
服务:
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 :(得分:4)
您必须使用此:
var changeId = function () {
console.log('pre change:' + id);
this.id = 'World';
console.log('post change:' + id);
};
答案 1 :(得分:3)
问题是你有本地变量id:var id = 'Hello';
稍后在函数中将此局部变量的值复制到您返回的对象中:
return {
id: id,
changeId: changeId
};
所以从这里返回的对象有一个原始的id
,它是原始id变量的COPY,而你的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
设置为vm
和vm
反过来又是你返回的对象。因此,您可以访问返回的对象。但请注意,如果您执行以下代码:
var func = vm.clickHandler();
func();
这不一样。在这种情况下,this
不会设置为vm
,您就会丢失。当您选择基于this
的解决方案时,您应该了解这种情况。
答案 2 :(得分:1)
您在另一个对象中传递函数,并且更改了函数范围 尝试:
this.id = "World"
而不是
id = "World"