2015-10-26 7 views
20

Ist es nicht möglich (oder noch nicht möglich) von ngForngModel gegen Werte zu benutzen? Versucht Angular, mich vor schlechten Leistungen zu schützen?Angular2 ngModel gegen ngFor Variablen

Arbeiten groß: http://jsfiddle.net/langdonx/n5pjgev6/

<input type="text" [(ng-model)]="value">{{value}} 

nicht mehr so ​​große Arbeit: http://jsfiddle.net/langdonx/n5pjgev6/1

<li *ng-for="#name of names"> 
    <input type="text" [(ng-model)]="name">{{name}} 
</li> 

AUSNAHME: Es kann keine variable Bindung Namen

Ich habe versucht, die Bindung an die neu zuweisen Array auch, die ... Art von Arbeiten, bu t hijacks Fokus und wirft auch eine Ausnahme: http://jsfiddle.net/langdonx/n5pjgev6/2/

<li *ng-for="#name of names; #i = index"> 
    <input type="text" [(ng-model)]="names[i]">{{name}} 
</li> 

AUSNAHME: LifeCycle.tick genannt wird rekursiv

Edit:

Ich kann rund um die LifeCycle.tick Problem bekommen ein mit direkterer Ansatz, aber der Fokus gestohlen wird nach wie vor, weil ngFor Dinge neu gezeichnet: http://jsfiddle.net/langdonx/n5pjgev6/3/

012.351.
+0

http://teropa.info/blog/2015/06/09/transclusion.html die Absätze Lesen Sie Transklusion Scope Lifecycle verwalten und Rendern mit Element Transklusion Wiederholte. Könnte Ihnen ein wenig Einblick geben – cjds

+2

Seit einer späten Beta gibt es 'trackBy' verfügbar, um' ngModel' mit 'ngFor' arbeiten zu lassen, siehe http: // stackoverflow.com/questions/36469710/angular-2-ngmodel-binden-in-nested-ngfor –

+1

@ GünterZöchbauer Ziemlich durcheinander Sie würden dies als ein Duplikat für Ihre neuere Antwort markieren. – Langdon

Antwort

16

Ich glaube, ngFor nicht mögen Arrayelemente verfolgen, die primitive Werte sind ngModel auf ihnen.

Wenn Sie die ngModel innerhalb der Schleife zu entfernen, es funktioniert.

Es funktioniert auch, wenn ich update jsfiddle mit:

this.names = [{name: 'John'}, {name: 'Joe'}, {name: 'Jeff'}, {name: 'Jorge'}]; 

und

<li *ng-for="#n of names"><input type="text" [(ng-model)]="n.name">{{n.name}}</li> 
+0

Ich hatte das gleiche Problem und löste es, indem ich einen Wrapper um meinen Wert verwendete (genau das, was Sie oben getan haben). Aber lass mich fragen: Ist das ein Angular 2 Bug oder "Feature"? Ich bin mir nicht ganz sicher, warum das passiert. – AstrOne

+2

Kein Fehler. Strings sind Primitive, daher gibt es keine Referenzadresse, und ng2 verwendet stattdessen seinen Wert, um ihn innerhalb der Schleife (ngFor) zu identifizieren. Dann will ngModel diesen Wert ändern -> Exception – bertrandg

+0

Nicht versucht, aber ich denke, es verhält sich fast identisch mit ng1. – bertrandg

7

Eine Lösung ist es, den Wert innerhalb ngModel durch seinen Index zu verweisen. Daher [(ngModel)]="names[index]".

Aber dies ist nicht ausreichend, da *ngFor Spuren Elemente von Wert. Sobald der Wert geändert wird, kann der alte Wert nicht mehr verfolgt werden. Also müssen wir die Tracking-Funktion ändern, um einen Index zurückzugeben, also trackBy: trackByIndex.

Dieses Problem wird erklärt here.

Lösung:

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <input type="text" 
     *ngFor="let name of names; let nameIndex = index; trackBy: trackByIndex" 
     [(ngModel)]="names[nameIndex]"/> 
     <br/> 
     {{ names | json }} 
    </div> 
    `, 
}) 
export class App { 

    names: string[]; 

    constructor() { 
    this.names = ['a', 'b', 'c']; 
    } 

    public trackByIndex(index: number, item) { 
    return index; 
    } 
}