【发布时间】:2015-02-21 05:49:04
【问题描述】:
在我的 AngularJS 应用程序中,我通常使用 $rootScope 传递数据。在各种状态下,我会在必要时将它们拉入 $scope。但是由于 $scope 具有原型继承,我想这只是为了可读性而不是其他。在我的应用中,有以下变量...
$rootScope.list // object
$rootScope.list.items // array
$rootScope.additions // array
$rootScope.cart // object
$rootScope.cart.items // array
在我开始之前,这通常以伪代码的形式列出。因此,如果它不正确,那也没关系。我正在寻找概念上的理解。
起初,购物车是空的。您查看list.items 并将单个列表项复制到cart.items 数组中。这很好用,直到我们开始讨论具有唯一 additions 的重复项。
比如说,我想要 2 件相同的商品,除了一件商品有不同的添加(购物车商品有数量属性,而不是列出商品)。
$rootScope.cart.items = [
{
name: 'listItem1',
quantity: 3,
additions: ['addition1']
}, {
name: 'listItem2',
quantity: 1,
additions: ['addition2']
}, {
name: 'listItem1', // same as cart.items[1], but additions has diff values
quantity: 1,
additions: ['addition1','addition2']
}];
首先,AngularJS 抱怨,因为我的 ng-repeater 中有重复项。我通过在ng-repeat 指令中附加track by $index 解决了这个问题。这也是我看到的第一个危险信号,告诉我我做错了什么。
我的第一个想法是创建一个临时的cartItem,随意添加它的添加,然后将其推送到$rootScope.cart.items[]。但是,当需要将第三个购物车项目推送到购物车时,它是第一个列表项目的另一个副本,它会覆盖第一个购物车项目的 additions[]。所以,$rootScope.cart.items 看起来像这样:
$rootScope.cart.items = [
{
name: 'listItem1',
quantity: 3,
additions: ['addition1','addition2']
}, {
name: 'listItem2',
quantity: 1,
additions: ['addition2']
}, {
name: 'listItem1', // same as cart.items[1], but additions has diff values
quantity: 1,
additions: ['addition1','addition2']
}];
从这个结果来看,在将 $rootScope 变量从一个地方复制到另一个地方时,它表面上是按引用传递的。
所以,我的下一个想法是尝试使用具有隔离作用域的指令。但我很快意识到我的逻辑是错误的。虽然隔离范围会给我单向数据绑定,但它并不是我希望的方向。指令的父范围仍然可以设置值。
我最理想的做法是任意将 list.items 添加到 cart.items。但是任何来自同一个列表项的购物车项目,我都希望彼此不绑定。因此,一个副本中的添加可能与另一副本中的添加不同。 实现这一目标的最佳方式是什么?我觉得使用 $rootScope 在我的应用程序中的状态之间传递数据可能是一个糟糕的决定,尽管这是我拥有的最快的方式找到了。
【问题讨论】:
-
docs.angularjs.org/api/ng/function/angular.copy -- 这将帮助您制作数组的副本。另外,是的,您应该尽量不使用 rootScope,总有另一种方法。在您的情况下,您可以使用工厂
-
太好了,我想这会使
$rootScope.cart.items成为$rootScope.list.items的浅拷贝。如果您想对此做出回答,我将不胜感激!越详细越好。 -
对,只是指我之前的实现。
标签: javascript angularjs angularjs-scope