116

我正在尝试允许用户使用ngRepeatand来编辑项目列表ngModel。(请参阅this fiddle。)但是,我尝试过的两种方法都会导致奇怪的行为:一种不会更新模型,另一种会在每次按键时模糊表单。

我在这里做错了吗?这不是受支持的用例吗?

这是小提琴中的代码,为方便起见复制:

<html ng-app>
    <head>
        <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet">
    </head>
    <body ng-init="names = ['Sam', 'Harry', 'Sally']">
        <h1>Fun with Fields and ngModel</h1>
        <p>names: {{names}}</p>
        <h3>Binding to each element directly:</h3>
        <div ng-repeat="name in names">
            Value: {{name}}
            <input ng-model="name">                         
        </div>
        <p class="muted">The binding does not appear to be working: the value in the model is not changed.</p>
        <h3>Indexing into the array:</h3>
        <div ng-repeat="name in names">
            Value: {{names[$index]}}
            <input ng-model="names[$index]">                         
        </div>
        <p class="muted">Type one character, and the input field loses focus. However, the binding appears to be working correctly.</p>
    </body>
</html>

​</p>

4

8 回答 8

120

这似乎是一个有约束力的问题。

建议不要绑定到原语

ngRepeat当它应该迭代对象时,您正在迭代集合中的字符串。解决您的问题

<body ng-init="models = [{name:'Sam'},{name:'Harry'},{name:'Sally'}]">
    <h1>Fun with Fields and ngModel</h1>
    <p>names: {{models}}</p>
    <h3>Binding to each element directly:</h3>
    <div ng-repeat="model in models">
        Value: {{model.name}}
        <input ng-model="model.name">                         
    </div>

jsfiddle:http: //jsfiddle.net/jaimem/rnw3u/5/

于 2012-12-05T02:25:12.537 回答
73

使用 Angular 最新版本 (1.2.1) 并通过$index. 此问题已修复

http://jsfiddle.net/rnw3u/53/

<div ng-repeat="(i, name) in names track by $index">
    Value: {{name}}
    <input ng-model="names[i]">                         
</div>
于 2014-02-06T12:52:53.773 回答
43

当需要了解scopesngRepeatngModelNgModelController的工作方式时,你会陷入困境。也尝试使用 1.0.3 版本。你的例子会有所不同。

您可以简单地使用 jm- 提供的解决方案

但如果你想更深入地处理这种情况,你必须了解:

  • AngularJS 是如何工作的
  • 范围具有层次结构;
  • ngRepeat 为每个元素创建新范围;
  • ngRepeat 构建带有附加信息的项目缓存(hashKey);在每次监视调用每个新项目(不在缓存中)时,ngRepeat 构造新范围、DOM 元素等。更详细的描述
  • 从 1.0.3 开始,ngModelController 使用实际模型值重新呈现输入。

您的示例“直接绑定到每个元素”如何适用于 AngularJS 1.0.3:

  • 您在输入中输入字母'f'
  • ngModelController更改项目范围的模型(名称数组未更改)=> name == 'Samf', names == ['Sam', 'Harry', 'Sally'];
  • $digest循环开始;
  • ngRepeat将项目范围 ( 'Samf') 中的模型值替换为未更改名称数组 ( 'Sam') 中的值;
  • ngModelController使用实际模型值 ( 'Sam') 重新呈现输入。

您的示例“索引到数组”如何工作:

  • 您在输入中输入字母'f'
  • ngModelController更改名称中的项目array=> `names == ['Samf', 'Harry', 'Sally'];
  • $digest 循环开始;
  • ngRepeat'Samf'在缓存中找不到;
  • ngRepeat创建新范围,使用新输入添加新 div 元素(这就是输入字段失去焦点的原因 - 具有旧输入的旧 div 被具有新输入的新 div 替换);
  • 呈现新 DOM 元素的新值。

此外,您可以尝试使用AngularJS Batarang并查看 $id 如何通过您输入的输入更改 div 范围的 $id。

于 2012-12-05T13:09:58.633 回答
6

如果您不需要模型在每次击键时更新,只需绑定到name然后在 blur 事件上更新数组项:

<div ng-repeat="name in names">
    Value: {{name}}
    <input ng-model="name" ng-blur="names[$index] = name" />
</div>
于 2014-08-09T22:06:22.513 回答
4

我刚刚将 AngularJs 更新到 1.1.2 并且没有问题。我想这个错误是固定的。

http://ci.angularjs.org/job/angular.js-pete/57/artifact/build/angular.js

于 2013-01-21T13:29:37.567 回答
2

问题似乎在于如何ng-model使用input和覆盖name对象,使其丢失ng-repeat

作为一种解决方法,可以使用以下代码:

<div ng-repeat="name in names">
    Value: {{name}}
    <input ng-model="names[$index]">                         
</div>

希望能帮助到你

于 2017-07-10T08:17:23.990 回答
1

我尝试了上面的解决方案来解决我的问题,它就像一个魅力。谢谢!

http://jsfiddle.net/leighboone/wn9Ym/7/

这是我的版本:

var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
    $scope.models = [{
        name: 'Device1',
        checked: true
    }, {
        name: 'Device1',
        checked: true
    }, {
        name: 'Device1',
        checked: true
    }];

}

和我的 HTML

<div ng-app="myApp">
    <div ng-controller="MyCtrl">
         <h1>Fun with Fields and ngModel</h1>
        <p>names: {{models}}</p>
        <table class="table table-striped">
            <thead>
                <tr>
                    <th></th>
                    <th>Feature 1</td>
                    <th>Feature 2</th>
                    <th>Feature 3</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>Device</td>
                   <td ng-repeat="modelCheck in models" class=""> <span>
                                    {{modelCheck.checked}}
                                </span>

                    </td>
                </tr>
                <tr>
                    <td>
                        <label class="control-label">Which devices?</label>
                    </td>
                    <td ng-repeat="model in models">{{model.name}}
                        <input type="checkbox" class="checkbox inline" ng-model="model.checked" />
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
于 2013-07-05T23:05:04.257 回答
-5

怎么做:

<select ng-model="myModel($index+1)">

在我的检查员元素中是:

<select ng-model="myModel1">
...
<select ng-model="myModel2">
于 2015-09-02T19:46:32.530 回答