2014-09-26 76 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"