wake-up-neo.com

Schwierigkeiten mit ng-Modell, ng-Wiederholung und Eingaben

Ich versuche, dem Benutzer das Bearbeiten einer Liste von Elementen mithilfe von ngRepeat und ngModel zu ermöglichen. ( Siehe diese Fiedel .) Beide Ansätze, die ich ausprobiert habe, haben jedoch zu einem bizarren Verhalten geführt: Der eine aktualisiert das Modell nicht und der andere verwischt das Formular bei jedem Tastendruck.

Mache ich hier etwas falsch? Ist dies kein unterstützter Anwendungsfall?

Hier ist der Code von der Geige, der der Einfachheit halber kopiert wurde:

<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>

Für den Fall, dass Sie nicht mehr weiterkommen möchten

115
Nick Heiner

Dies scheint ein verbindliches Thema zu sein.

Der Rat lautet nicht an Primitive binden .

Ihr ngRepeat iteriert über Zeichenfolgen in einer Auflistung, wenn es über Objekte iterieren soll. Um Ihr Problem zu beheben

<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/

120
jaime

Verwenden von Angular neueste Version (1.2.1) und verfolgen von $index. Dieses Problem ist behoben

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

<div ng-repeat="(i, name) in names track by $index">
    Value: {{name}}
    <input ng-model="names[i]">                         
</div>
70
Thilaga

Sie geraten in eine schwierige Situation, wenn Sie verstehen müssen, wie Bereiche , ngRepeat und ngModel mit NgModelController funktionieren. Versuchen Sie auch, Version 1.0.3 zu verwenden. Ihr Beispiel wird etwas anders funktionieren.

Sie können einfach die von jm-

Wenn Sie sich jedoch eingehender mit der Situation befassen möchten, müssen Sie Folgendes verstehen:

  • wie AngularJS funktioniert ;
  • bereiche haben eine hierarchische Struktur;
  • ngRepeat erstellt für jedes Element einen neuen Bereich.
  • ngWiederholter Build-Cache für Elemente mit zusätzlichen Informationen (hashKey); Bei jedem Überwachungsaufruf für jedes neue Element (das sich nicht im Cache befindet) erstellt ngRepeat einen neuen Gültigkeitsbereich, ein neues DOM-Element usw. nähere Beschreibung .
  • ab 1.0.3 rendert ngModelController Eingaben mit aktuellen Modellwerten.

So funktioniert Ihr Beispiel "Direktes Binden an jedes Element" für AngularJS 1.0.3:

  • sie geben den Buchstaben 'f' in die Eingabe ein.
  • ngModelController ändert das Modell für den Objektbereich (das Namensarray wird nicht geändert) => name == 'Samf', names == ['Sam', 'Harry', 'Sally'];
  • Die $digest - Schleife wird gestartet.
  • ngRepeat ersetzt den Modellwert aus dem Artikelbereich ('Samf') durch den Wert aus dem Array mit den unveränderten Namen ('Sam');
  • ngModelController gibt die Eingabe mit dem tatsächlichen Modellwert wieder ('Sam').

So funktioniert Ihr Beispiel "Indizieren in das Array":

  • sie geben den Buchstaben 'f' in die Eingabe ein.
  • ngModelController ändert Element in Namen array => `names == ['Samf', 'Harry', 'Sally'];
  • $ digest loop wird gestartet;
  • ngRepeat kann 'Samf' nicht im Cache finden;
  • ngRepeat erstellt einen neuen Bereich, fügt ein neues div-Element mit neuer Eingabe hinzu (aus diesem Grund verliert das Eingabefeld den Fokus - altes div mit alter Eingabe wird durch neues div mit neuer Eingabe ersetzt);
  • neue Werte für neue DOM-Elemente werden gerendert.

Sie können auch versuchen, AngularJS Batarang zu verwenden, um zu sehen, wie sich $ id des Bereichs von div mit der Eingabe ändert, in die Sie eingeben.

43
Artem Andreev

Wenn Sie das Modell nicht bei jedem Tastendruck aktualisieren müssen, binden Sie es einfach an name und aktualisieren Sie dann das Array-Element bei einem Unschärfeereignis:

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

Ich habe gerade AngularJs auf 1.1.2 aktualisiert und habe kein Problem damit. Ich denke, dieser Fehler wurde behoben.

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

4
Anton Rodin

Das Problem scheint in der Art und Weise zu liegen, wie ng-model Mit input zusammenarbeitet und das Objekt name überschreibt, sodass es für ng-repeat Verloren geht.

Um dieses Problem zu umgehen, können Sie den folgenden Code verwenden:

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

Ich hoffe es hilft

2
Draško Kokić

Ich habe versucht, die Lösung oben für mein Problem, es funktionierte wie ein Zauber. Vielen Dank!

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

Hier ist meine Version davon:

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

}

und mein 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>
1
Leigh Lawhon