AngularJS - 服务公开字符串

时间:2014-09-26 21:11:27

标签: javascript angularjs angular-services

我有一个问题,我有一个公开字符串的服务。此服务上有一个函数可以更新字符串的值。该服务在内部知道该值已更改,但是,外部值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/

3 个答案:

答案 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设置为vmvm反过来又是你返回的对象。因此,您可以访问返回的对象。但请注意,如果您执行以下代码:

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

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

答案 2 :(得分:1)

您在另一个对象中传递函数,并且更改了函数范围 尝试:

this.id = "World"

而不是

id = "World"