$ scope和$ apply中的Angular替换数组不起作用

时间:2017-03-25 00:17:16

标签: javascript angularjs arrays

我有一个相当大的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。但是,当我第一次收到范围时,它是控制器的范围 - 从其价值确认。

也许别人知道的更好?

1 个答案:

答案 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