angularjs - not - option ng repeat ng model
Dificultad con ng-model, ng-repeat y entradas (8)
Acabo de actualizar AngularJs a 1.1.2 y no tengo ningún problema con eso. Supongo que este error fue corregido.
http://ci.angularjs.org/job/angular.js-pete/57/artifact/build/angular.js
Estoy tratando de permitir que el usuario edite una lista de elementos usando ngRepeat
y ngModel
. ( Ver este violín .) Sin embargo, ambos enfoques que he intentado conducen a un comportamiento extraño: uno no actualiza el modelo, y el otro difumina el formulario en cada keydown.
¿Estoy haciendo algo mal aquí? ¿No es esto un caso de uso compatible?
Aquí está el código del violín, copiado por conveniencia:
<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>
1.
El problema parece estar en la forma en que ng-model
funciona con la input
y sobrescribe el objeto de name
, haciéndolo perdido para ng-repeat
.
Como solución, uno puede usar el siguiente código:
<div ng-repeat="name in names">
Value: {{name}}
<input ng-model="names[$index]">
</div>
Espero eso ayude
Esto parece ser un problema vinculante.
El consejo es que no se unen a los primitivos .
Su ngRepeat
itera sobre cadenas dentro de una colección, cuando debería iterar sobre objetos. Para arreglar tu problema
<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/
Probé la solución anterior para mi problema que funcionaba como un encanto. ¡Gracias!
http://jsfiddle.net/leighboone/wn9Ym/7/
Aquí está mi versión de eso:
var myApp = angular.module(''myApp'', []);
function MyCtrl($scope) {
$scope.models = [{
name: ''Device1'',
checked: true
}, {
name: ''Device1'',
checked: true
}, {
name: ''Device1'',
checked: true
}];
}
y mi 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>
Si no necesita que el modelo se actualice con cada golpe de tecla, simplemente conéctese al name
y luego actualice el elemento de la matriz en el evento de desenfoque:
<div ng-repeat="name in names">
Value: {{name}}
<input ng-model="name" ng-blur="names[$index] = name" />
</div>
Utilizando la última versión de Angular (1.2.1) y rastrea por $index
. Este problema está arreglado
<div ng-repeat="(i, name) in names track by $index">
Value: {{name}}
<input ng-model="names[i]">
</div>
como hacer algo como:
<select ng-model="myModel($index+1)">
Y en mi elemento de inspector ser:
<select ng-model="myModel1">
...
<select ng-model="myModel2">
ngRepeat en una situación difícil cuando es necesario comprender cómo funcionan los scopes , ngRepeat y ngModel con NgModelController . También intente usar la versión 1.0.3. Tu ejemplo funcionará de forma un poco diferente.
Simplemente puede usar la solución provista por jm-
Pero si quieres lidiar con la situación más profundamente, debes entender:
- cómo funciona AngularJS ;
- los ámbitos tienen una estructura jerárquica;
- ngRepeat crea un nuevo alcance para cada elemento;
- ngRepetir la caché de compilación de elementos con información adicional (hashKey); en cada llamada al reloj para cada elemento nuevo (que no está en la caché) ngRepeat construye un nuevo alcance, elemento DOM, etc. Descripción más detallada .
- desde 1.0.3 ngModelController reindica las entradas con los valores reales del modelo.
Cómo funciona su ejemplo "Enlace a cada elemento directamente" para AngularJS 1.0.3:
- ingresas la letra
''f''
en la entrada; -
ngModelController
cambia el modelo para el alcance del artículo (los nombres de la matriz no se cambian) =>name == ''Samf''
,names == [''Sam'', ''Harry'', ''Sally'']
; -
$digest
loop se inicia; -
ngRepeat
reemplaza el valor del modelo del alcance del artículo (''Samf''
) por el valor del conjunto de nombres sin modificar (''Sam''
); -
ngModelController
entrada con el valor real del modelo (''Sam''
).
Cómo funciona su ejemplo "Indexación en la matriz":
- ingresas la letra
''f''
en la entrada; -
ngModelController
cambia el elemento en los nombresarray
=> `names == [''Samf'', ''Harry'', ''Sally'']; - $ digest loop se inicia;
-
ngRepeat
no puede encontrar''Samf''
en el caché; -
ngRepeat
crea un nuevo ámbito, agrega un nuevo elemento div con una nueva entrada (es por eso que el campo de entrada pierde el foco - el div viejo con la entrada anterior se reemplaza por el nuevo div con la nueva entrada); - se muestran nuevos valores para los nuevos elementos DOM.
Además, puedes intentar utilizar AngularJS Batarang y ver cómo cambia $ id del ámbito de div con la entrada en la que ingresas.