ng-model,ng-repeat和输入有困难

Nic*_*ner 116 angularjs angularjs-ng-repeat angularjs-ng-model

我试图允许用户使用ngRepeat和编辑项目列表ngModel.(看到这个小提琴.)但是,我尝试过的两种方法都会导致奇怪的行为:一个不更新模型,另一个模糊每个keydown上的形式.

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

以下是小提琴的代码,为方便起见而复制:

<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>
Run Code Online (Sandbox Code Playgroud)

jai*_*ime 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>
Run Code Online (Sandbox Code Playgroud)

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

  • 感谢第一个超链接,因为它解释了焦点/闪烁问题的模糊/丢失.我总是想知道为什么会这样. (3认同)
  • 谢谢你,帮了很多忙.仍然,绑定到原始人应该在那里... (2认同)

Thi*_*aga 70

使用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>
Run Code Online (Sandbox Code Playgroud)


Art*_*eev 43

当有必要了解范围,ngRepeatngModelNgModelController如何工作时,您会陷入困境.也尝试使用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将item scope('Samf')中的模型值替换为未更改名称array('Sam')的值;
  • ngModelController使用实际模型值('Sam')重新输入输入.

您的示例"索引到数组"的工作原理如何:

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

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


Bil*_*man 6

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

<div ng-repeat="name in names">
    Value: {{name}}
    <input ng-model="name" ng-blur="names[$index] = name" />
</div>
Run Code Online (Sandbox Code Playgroud)