【问题标题】:why do two ng-repeats share same scope?为什么两个 ng-repeats 共享相同的范围?
【发布时间】:2014-02-02 17:46:49
【问题描述】:

我有两个具有相同列表的 ng-repeat 的 div。但是当我从第一个 div 更改一个列表项的内容时,第二个 div 接收相同的值。我认为 ng-repeats 有孤立的范围?如何归档 ng-repeats 的隔离?

编辑: “在大多数情况下,指令和作用域交互但不会创建新的作用域实例。但是,某些指令,例如 ng-controller 和 ng-repeat,会创建新的子作用域并将子作用域附加到对应的 DOM 元素。” http://docs.angularjs.org/guide/scope

<div ng-controller="MyCtrl">
<button ng-click="newitem()">add item </button>
<div ng-repeat="item in list">
    <input ng-model="item.name" placeholder="Name*">
    <input ng-model="item.lastname" placeholder="Last name*">
    <input ng-model="item.username" placeholder="Username(Email)*">
</div>
        here is another div with ng-repeat of the same list. why do they share scope? 
        <br>
<div ng-repeat="item in list">
    <input ng-model="item.name" placeholder="Name*">
    <input ng-model="item.lastname" placeholder="Last name*">
    <input ng-model="item.username" placeholder="Username(Email)*">
</div>

js:

 var myApp = angular.module('myApp', []);
function MyCtrl($scope) {

$scope.list = [];

$scope.newitem = function () {
    $scope.list.push({name: "", lastname: "", username: ""});
}
}

http://jsfiddle.net/LZKq2/

【问题讨论】:

  • 因为最终您在同一个控制器中使用相同的数据源,如果您想更改一个列表而不更改另一个列表,然后复制该列表?
  • 但是 ng-repeat 根据 angularjs 创建了新的范围?我真的认为 ng-repeat 是从父级(控制器范围)继承的,然后对它所做的新范围进行了所有更改。
  • 我确实知道实现目标的方法,但我仍然想要对此进行解释。我的解决方法是创建一个新的控制器实例。

标签: angularjs angularjs-ng-repeat


【解决方案1】:

我将尝试以与其他答案不同的方式来解释这一点,尽管所有答案基本上都在说同样的事情。

当您将控制器附加到 div 元素时,它会创建一个附加了 $scope 的控制器实例,您可以在其中添加一个数组。将数组附加到第一个子 div 并使用 ng-repeat 的那一刻,您将获得一个属于该数组的子范围。第二个子 div 不是创建一个新数组,而是重新使用现在已经有一个范围的现有数组。因此,通过第一个 div 添加到数组中的项目将反映在第二个 div 中。它不可能以任何其他方式发挥作用,因为您只有一个要在 $scope 中跟踪的变量。但是,如果您有 2 个单独的列表,例如 $scope.list 和 $scope.list2,那么这两个数组将各有自己的范围。见http://jsfiddle.net/zTE5j/2/

<div ng-controller="MyCtrl">
<button ng-click="newitem()">add item </button>
<div ng-repeat="item in list">
    <input ng-model="item.name" placeholder="Name*">
    <input ng-model="item.lastname" placeholder="Last name*">
    <input ng-model="item.username" placeholder="Username(Email)*">
</div>
        here is another div with ng-repeat of the same list. why do they share scope? 
        <br>
<div ng-repeat="item in list2">
    <input ng-model="item.name" placeholder="Name*">
    <input ng-model="item.lastname" placeholder="Last name*">
    <input ng-model="item.username" placeholder="Username(Email)*">
</div>
</div>

控制器:

var myApp = angular.module('myApp', []);

function MyCtrl($scope) {

$scope.list = [];
$scope.list2 = [];

$scope.newitem = function () {
    $scope.list.push({name: "", lastname: "", username: ""});
    $scope.list2.push({name: "", lastname: "", username: ""});
}
}

【讨论】:

    【解决方案2】:

    新作用域是子作用域,因此尽管作用域是新的,但作用域上的属性是从父作用域继承的。例如,如果父级具有项目列表,则子范围继承相同的项目列表。将其视为“指向父列表的指针”。当您修改第一个列表中的项目“x”时,项目“x”在范围上的列表中。该列表继承自父列表,因此修改“item x”与修改父列表中的该项相同。因为第二个列表继承自父项,它也具有对“项目 x”的相同引用,因此它将反映更新。

    这在这个小提琴中得到了证明:http://jsfiddle.net/jeremylikness/xdzxb/

    请注意,当您编辑项目时,两个列表都会受到影响,但第三个列表不会因为它是作为副本创建的:

    $scope.listNew = $scope.list.slice(0);
    

    如果您希望重复作用于列表的不同版本,则需要明确创建副本。

    【讨论】:

      【解决方案3】:

      ng-repeat do 根据 angularjs 创建新的作用域。

      但是你有一个普通对象中的 toString 吗?

      var a={};
      if (a.toString) alert('1');// ( where the hell this toString came from ?)
      

      这将提醒 1 !!!

      这是因为原型继承。

      您的内联重复范围有自己的范围,它会为数据寻求其父范围(如果未找到)。

      为什么它们共享范围?

      因为他们看到的是同一个视图模型对象,$scope 是由控制器创建的。

      【讨论】:

      • 是的,我知道 javascript 继承模型。 NG-REPEAT 应该从控制器范围继承列表,然后创建自己的新子范围。所以如果 div1 创建 childscope1,而 div2 创建 childscope2。为什么 childscope1s 更改会影响 childscope2 ?我真的很困惑。我确信我在早期版本的 angualrjs 中注意到了这种范围继承模式。但他们一定在上一个版本中改变了一些东西。
      猜你喜欢
      • 2017-01-17
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      • 2019-05-18
      相关资源
      最近更新 更多