Angular.js, не может редактировать динамически созданные поля ввода
Используя angular.js, у меня есть динамический список полей формы, которые я хочу отобразить пользователю для редактирования (и последующей отправки):
var app = angular.module('app', []);
app.controller('Ctrl', function($scope) {
$scope.fields = {
foo: "foo",
bar: "bar",
baz: "baz"
};
});
И HTML:
<div ng-app="app" ng-controller="Ctrl">
<table>
<th>key</th>
<th>value</th>
<th>fields[key]</th>
<tr ng-repeat="(key,value) in fields">
<td>{{key}}:</td>
<td><input type="text" ng-model="value"/></td>
<td><input type="text" ng-model="fields[key]"/></td>
</tr>
</table>
</div>
Смотрите эту скрипту. По какой-то причине я не понимаю, что поля ввода текста не редактируются. Я пробовал два разных способа, как показано выше: value
и fields[key]
. value
не редактируется вообще, а fields[key]
позволит один нажатие клавиши, а затем оно размывается. Что я делаю не так? Спасибо.
Ответы
Ответ 1
Это редактируется, но после каждого нажатия клавиши ваше текстовое поле теряет фокус, так что вам нужно снова щелкнуть по нему, чтобы добавить еще один char.
И это происходит потому, что весь ваш шаблон повторно отображается после каждого изменения в любой из моделей. И после повторной обработки шаблона, в настоящее время нет способа узнать, какой вход должен быть сфокусирован. Таким образом, вы должны создать этот путь, и вы можете захотеть написать директиву, чтобы сосредоточиться на выбранном входе.
Ответ 2
SET ответил на вопрос, почему это происходит, но для достижения желаемого поведения нужно поддерживать отдельный массив ваших ключей и запускать ng-repeat с этих клавиш. Я добавил некоторые текстовые поля для тестирования, чтобы добавить дополнительные свойства в $scope.fields
Вы можете использовать $watch для динамического набора ключей при изменении значения свойства, если ваши требования состоят в том, что количество полей может измениться.
http://jsfiddle.net/aERwc/10/
Разметка
<div ng-app="app" ng-controller="Ctrl">
<table>
<th>key</th>
<th>value</th>
<tr ng-repeat="key in fieldKeys">
<td>{{key}}:</td>
<td><input type="text" ng-model="fields[key]"/></td>
</tr>
</table>
<div><h6>Add a field</h6>
key: <input type="text" ng-model="keyToAdd" /><br />
value: <input type="text" ng-model="valueToAdd" />
<button ng-click="addField()">Add Field</button>
</div>
</div>
контроллер
var app = angular.module('app', []);
app.controller('Ctrl', function($scope) {
$scope.fields = {
foo: "foo",
bar: "bar",
baz: "baz"
};
$scope.fieldKeys = [];
$scope.setFieldKeys = function() {
var keys = [];
for (key in $scope.fields) {
keys.push(key);
}
$scope.fieldKeys = keys;
}
$scope.addField = function() {
$scope.fields[$scope.keyToAdd] = $scope.valueToAdd;
$scope.setFieldKeys();
$scope.keyToAdd = '';
$scope.valueToAdd = '';
}
$scope.setFieldKeys();
});
Ответ 3
Вам нужно использовать массив объектов. Надеюсь, вы сможете переделать свою модель:
$scope.fields = [
{label: "foo", value: "foov"},
{label: "bar", value: "barv"},
{label: "baz", value: "bazv"}
];
<tr ng-repeat="field in fields">
<td>{{field.label}}:</td>
<td><input type="text" ng-model="field.value">
Fiddle.