2017-02-06 6 views
0

ich eine kleine Komponente schreiben, die aus mehreren Zeilen bestehen und jede Zeile besteht aus:Angular 2 Datenbindung bricht

  1. Drop-Down mit zwei möglichen Entscheidungen - nennen Sie es „type“
  2. Eingabefeld - Name es "Schlüssel"
  3. Eingabefeld/Drop-Down auf der "Art" (Wert aus dem ersten Dropdown), je - nennen sie es "Wert"

Das erwartete Verhalten ist:

  1. Wenn der Benutzer "Constant" aus dem ersten Dropdown wählt, sollte das 3. Element ein Eingabefeld sein. Wenn es "Variable" ist, sollte es zu einem Dropdown-Menü werden.
  2. Wenn der Benutzer sowohl die Felder "Schlüssel" als auch "Wert" eingibt, sollte die neue Zeile für einen anderen Eintrag angezeigt werden. Ein solches Verhalten sollte immer dann ausgelöst werden, wenn sich "Schlüssel" oder "Wert" ändert.
  3. Wenn der Benutzer entweder "Schlüssel" oder "Wert" aus der Zeile entfernt, die nicht die letzte Zeile ist, sollte diese Zeile entfernt werden. Dies sollte nur passieren, wenn der "Schlüssel" oder "Wert" den Fokus verliert.

Ich habe so etwas wie dies: sample on plunker

@Component({ 
    selector: 'my-app', 
    template: ` 
<div *ngFor="let rec of records"> 
    <select style="width: 75px;" class="select-field" [(ngModel)]="rec.type" (ngModelChange)="onTypeChange(rec)"> 
    <option *ngFor="let type of rec.types">{{type}}</option> 
    </select> 

    <input type="text" class="input-fields" [(ngModel)]="rec.key" (ngModelChange)="onValueChange(rec)" (blur)="onFocusLost(rec)"/> 

    <input *ngIf="rec.type == 'Constant'" type="text" class="input-fields" [(ngModel)]="rec.value" (ngModelChange)="onValueChange(rec)" (blur)="onFocusLost(rec)"/> 
    <span *ngIf="rec.type == 'Variable'"> 
     <select style="width: 75px;margin-left: 10px;" class="select-field" [(ngModel)]="rec.value" (ngModelChange)="onValueChange(rec)" (blur)="onFocusLost(rec)"> 
     <option></option> 
     <option *ngFor="let field of fields">{{field}}</option> 
     </select> 
    </span> 
</div> 
    `, 
}) 

export class App { 
records: FieldSelectionRecord[] = [new FieldSelectionRecord()]; 
fields: string[] = ['foo1', 'foo2']; 

    onTypeChange(record: FieldSelectionRecord) { 
    record.value = ""; 
    } 

    onValueChange(changedRecord: FieldSelectionRecord) { 
    if (this.isLastElement(changedRecord) && this.isRecordFullyFilled(changedRecord)) { 
     this.records.push(new FieldSelectionRecord()); 
    } 
    } 



    onFocusLost(changedRecord: FieldSelectionRecord) { 
    if (!this.isLastElement(changedRecord) && !this.isRecordFullyFilled(changedRecord)) { 
     this.records = this.records.filter(record => record != changedRecord); 
    } 
    } 

    private isLastElement(record: FieldSelectionRecord): boolean { 
    let index = this.records.indexOf(record); 
    return this.records.length - 1 === index; 
    } 

    private isRecordFullyFilled(record: FieldSelectionRecord): boolean { 
    return record.value.length > 0 && record.key.length > 0; 
    } 

} 

Obwohl es nicht wirklich vor sich wie erwartet funktioniert. Wenn Sie beispielsweise Schlüssel und Wert eingeben, wird die neue Zeile angezeigt. Wenn Sie auf die vorherige Zeile klicken und ihren Typ in eine Variable ändern, wird der Wert in Dropdown nicht geändert. Das Entfernen der vorherigen Zeilen funktioniert auch nicht immer. Ich habe es getestet und ich glaube, dass die zugrunde liegenden Werte geändert werden, aber die Ansicht wird nicht aktualisiert.

Was ist überraschend ist, dass ich eine andere Komponente hatte, die genau das gleiche ohne Verwendung von "Schlüssel" war - nur "Typ" und "Wert" und es funktioniert perfekt. Working sample here

Der einzige Unterschied dieser Zeile fehlt:

<input type="text" class="input-fields" [(ngModel)]="rec.key" (ngModelChange)="onValueChange(rec)" (blur)="onFocusLost(rec)"/> 

und isRecordFullyFilled Methode.

Ich versuchte, keine Zwei-Wege-Bindung zu verwenden, aber es half auch nicht. Was mache ich hier falsch?

Antwort

1

Wenn Sie auf Browser-Konsole schauen, können Sie einen Fehler bemerken:

VM3717 core.umd.js:3066 ORIGINAL EXCEPTION: Cannot read property 'length' of undefined

So versuchen value zu überprüfen, bevor length

private isRecordFullyFilled(record: FieldSelectionRecord): boolean { 
    return record.value && record.value.length > 0 && record.key.length > 0; 
} 

https://plnkr.co/edit/MbmX6G5ufr5HNGWzyMZv?p=preview

+0

So dumm von mir zu lesen. Aus irgendeinem seltsamen Grund taucht dieser Fehler bei PLNKR auf, während er in meiner lokalen Instanz keinen Fehler protokolliert. Danke vielmals – vers

Verwandte Themen