Трудности с НГ-модель, НГ-повторите, а входы
Я пытаюсь разрешить пользователю редактировать список элементов с помощью 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>
8 ответов:
это, кажется, является обязательным вопросом.
советы не привязывайтесь к примитивам.
код
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/
использование угловой последней версии (1.2.1) и отслеживать по
$index
. Эта проблема исправлена<div ng-repeat="(i, name) in names track by $index"> Value: {{name}} <input ng-model="names[i]"> </div>
вы попадаете в сложную ситуацию, когда нужно понять, как области,ngRepeat и ngModel С NgModelController работа. Также попробуйте использовать версию 1.0.3. Ваш пример будет работать немного по-другому.
вы можете просто использовать решение, предоставленное jm -
но если вы хотите справиться с ситуацией более глубоко, вы должны понять:
- как AngularJS не работает;
- области имеют иерархическую структуру;
- ngRepeat создает новую область для каждого элемента;
- ngRepeat построить кэш элементов с дополнительной информацией (hashKey); на каждой прямой вызов для каждого нового элемента (то есть не в кэше) ngRepeat создает новый контекст, DOM-элемент, и т. д. более подробное описание.
- от 1.0.3 ngmodelcontroller rerenders входы с фактической моделью ценности.
как ваш пример "привязка к каждому элементу напрямую" работает для AngularJS 1.0.3:
- введите букву
'f'
на входе;ngModelController
изменяет модель для области элемента (массив имен не изменяется) =>name == 'Samf'
,names == ['Sam', 'Harry', 'Sally']
;$digest
цикл запускается;ngRepeat
заменяет значение Модели из области элемента ('Samf'
) по значению из массива неизмененных имен ('Sam'
);ngModelController
rerenders ввод с фактическим значением модели ('Sam'
).как работает ваш пример "индексирование в массив":
- введите букву
'f'
на входе;ngModelController
изменяет элемент в именахarray
= > ' names = = ['Samf', 'Harry','Sally'];- $digest цикл запущен;
ngRepeat
не могу найти'Samf'
в кэш;ngRepeat
создает новую область, добавляет новый элемент div с новым входом (именно поэтому вход поле теряет фокус-старый div со старым входом заменяется новым div с новым входом);- отображаются новые значения для новых элементов DOM.
также вы можете попробовать использовать AngularJS Batarang и посмотрите, как изменяется $id области div с вводом, в который вы вводите.
Если вам не нужна модель для обновления с каждым нажатием клавиши, просто привязать к
name
а затем обновить элемент массива на событие размытия:<div ng-repeat="name in names"> Value: {{name}} <input ng-model="name" ng-blur="names[$index] = name" /> </div>
Я только что обновил AngularJs до 1.1.2 и не имею никаких проблем с ним. Я думаю эта ошибка была исправлена.
http://ci.angularjs.org/job/angular.js-pete/57/artifact/build/angular.js
проблема, кажется, в том, как
ng-model
работает сinput
и перезаписываетname
объект, что делает его потерянным дляng-repeat
.в качестве обходного пути можно использовать следующий код:
<div ng-repeat="name in names"> Value: {{name}} <input ng-model="names[$index]"> </div>
надеюсь, что это помогает
я попробовал решение выше для моей проблемы в нем работал как шарм. Спасибо!
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>