Angularjs 为什么ng init=";事物=[&x2026;];currentThing=things[0]”;使用ng click=";currentThing=thing";不更新绑定值?

Angularjs 为什么ng init=";事物=[&x2026;];currentThing=things[0]”;使用ng click=";currentThing=thing";不更新绑定值?,angularjs,Angularjs,请参阅下面的最小AngularJS应用程序 我的预期是,单击一个li会改变段落中的名称和编号,但它们不会改变其原始值。你知道为什么吗 <div ng-app ng-init="things=[ { name: 'one', num: 1 }, { name: 'two', num: 2 } ]; currentThing = things[0]"> <p>name: {{currentThing.name}} num: {{currentThing.num}}<

请参阅下面的最小AngularJS应用程序

我的预期是,单击一个
li
会改变段落中的名称和编号,但它们不会改变其原始值。你知道为什么吗

<div ng-app ng-init="things=[ { name: 'one', num: 1 }, { name: 'two', num: 2 } ]; currentThing = things[0]">
  <p>name: {{currentThing.name}} num: {{currentThing.num}}</p>
  <ul>
    <li ng-click="currentThing=thing" ng-repeat="thing in things">{{thing.name}}</li>
  </ul>
</div>

名称:{{currentThing.name}}num:{{{currentThing.num}

  • {{{thing.name}

可编辑、可运行的JSFIDLE:

这是因为在使用
ng repeat
时,每个模板实例都有自己的作用域,以及原型继承在JavaScript中的工作方式

简而言之,当您单击
li
元素时,它将在新创建的属于模板的子范围上创建currentThing属性,而不是更新父范围的
currentThing

如果改用此选项并单击第二个
li
,您将注意到它更新了自己的范围:

<li ng-click="currentThing=thing" ng-repeat="thing in things">
  <pre>{{ currentThing | json }}</pre>
</li>
  • {{currentThing}json}
  • 演示:

    解决此问题的推荐方法是使用对象,例如:

    
    名称:{{viewModel.currentThing.name}}num:{{{viewModel.currentThing.num}

    • {{{thing.name}
    演示:


    可以找到关于该问题的极好解释。

    尝试使用控制器而不是ng init;同样的事情,但如果我在控制器中的该方法中执行
    ng click=doIt(thing)
    并执行
    $scope.currentThing=thing
    ,它确实有效。为什么?将
    currentThing
    更改为
    things。currentThing
    也因某些原因起作用:
    <div ng-app ng-init="viewModel = { things: [ { name: 'one', num: 1 }, { name: 'two', num: 2 } ] }; viewModel.currentThing = viewModel.things[0]">
        <p>name: {{ viewModel.currentThing.name}} num: {{ viewModel.currentThing.num}}</p>
        <ul>
            <li ng-click="viewModel.currentThing = thing" ng-repeat="thing in viewModel.things">{{thing.name}}</li>
        </ul>
    </div>