我有一个相当大的Angular应用程序,有15个指令和5个服务。我遇到的问题与从服务中更新本地范围有关。并且通过更新我的意思是替换范围指向另一个数组的数组。
点击元素后,该过程如下:
clickDirective () {
restrict: 'A'.
link: function (scope, element, attrs) {
if ($rootScope.hasCertainValue) {
FirstService.handle(scope, valueX)
}
}
}
/* Calls FirstService.handle */
FirstService () {
handle (scope, valueX) {
if (certainCriteriaMet) {
SecondService.handle(scope, valueX)
}
}
}
/* Calls SecondService.handle */
SecondService () {
handle (scope, valueX) {
/* This is the funny part*/
console.log(scope.value) // let's assume prints: ['a']
// Option a)
scope.value = ['a', 'b'] // this is what I want to do
// Option b)
scope.value.push('b') // this is what works
scope.$apply()
// Now if we ran option a) the UI is not updated
console.log(scope.value) // prints ['a', 'b'] however
// But when this function is called the next time
// the value of scope.value has switched back to ['a'].
// If we ran option b) instead, the UI is updated
console.log(scope.value) // prints ['a', 'b'] as expected
// The difference is that the value of scope.value is
// still ['a', 'b'] the next time this function is called.
}
}
所以这里的问题是为什么我不能改变范围指向的对象?但我可以修改它吗?
SecondService包含另一个由另一个指令调用的函数,使用相同的作用域。在该函数中,我可以执行我想要的操作 - 这将用新的替换当前数组。
我能想到的唯一原因是某种竞争条件。
-----编辑-----
我想我已经开始在这里发现问题了。我在SecondService中使用的作用域对象只是指向实际作用域对象的指针。
scope.value ------> [阵列]
scope.atSecondService --------> scope.value -------> [阵列]
所以当我在scope.atSecondService更改数组时,这就是我得到的:
scope.value ------> [阵列]
scope.atSecondService -----> [newArray]< --- / --- scope.value
但是,这仍然让我想知道为什么我可以从另一个指令中调用类似的函数呢?
-----编辑2 -----
或许我错了。行为不一致。看起来我在元素级别创建了一个新的本地级别作用域,而不是在控制器上访问$ scope。但是,当我第一次收到范围时,它是控制器的范围 - 从其价值确认。
也许别人知道的更好?
答案 0 :(得分:2)
console.log(scope.value) // let's assume prints: ['a']
// Option a)
scope.value = ['a', 'b'] // this is what I want to do
// Option b)
scope.value.push('b') // this is what works
选项)您要用新的参考替换参考,意味着
原始scope.value
的引用将丢失并替换为
一个新的。
选项b )您只是更新数组,那就是
预期的行为。
如果你想清理数组并替换保留引用的所有内容,你应该试试这个:
scope.value.length = 0; //remove all the elements
[].push.apply(scope.value, ['a', 'b']); //push new values