2017-06-09 2 views
2

Ich habe eine einfache Dropdown, die von einem Array aufgefüllt wird. Benutzer bearbeiten einen Datensatz in einer Form, in der die Priorität des Datensatzes aus dem erwähnten Dropdown ausgewählt werden kann. Ich habe Schwierigkeiten beim Festlegen des ausgewählten Elements in diesem Dropdown. Hier ist mein Code für das Drop-Down-:Hinzufügen eines Attributs für eine Bedingung mit Winkel 2

<select *ngIf="formModel" [(ngModel)]="record.priority" formControlName="priority"> 
    <option value="-1">Select priority</option> 
    <option *ngFor="let priority of formModel.priorities" 
     [ngValue]="priority" 
     [innerHtml]="priority.name" 
     [selected]="priority.id == record.priority.id"></option> 
</select> 

Die ausgewählte Priorität der Aufzeichnung jedoch nicht ausgewählt ist, ist die resultierende HTML zeigt selected="true". Wenn ich den Code der folgenden ändern:

[selected]="(priority.id == record.priority.id ? '' : null)" 

Das Ergebnis ist selected="", aber die Option stil nicht ausgewählt. Ich habe bereits bestätigt, dass diese bestimmte Option ausgewählt werden sollte. Auch wenn ich den HTML-Code in Firebug auf nur selected ändern, ist die Option ausgewählt. Also meine Frage ist: Wie kann ich ein Attribut für eine bestimmte Bedingung hinzufügen, so dass das Attribut nicht zu anderen Elementen mit einem leeren Wert hinzugefügt wird?

+0

Ihr wählen 'ngModel' muss einen Wert haben, der in eine der Optionen ist. Hier sind Ihre Optionen Werte ein Objekt, und es ist ziemlich schwierig für das HTML, JS-Objekte zu lesen. Versuchen Sie stattdessen, in Ihren Optionswerten eine Eigenschaft wie 'name' oder' id' zu verwenden, und binden Sie Ihr ngModel ebenfalls daran. – trichetriche

Antwort

4

Mit zwei-Wege- zu schreiben ist Bindung wird in reaktiven Formen abgeraten. Der Punkt besteht darin, stattdessen die Formularsteuerelemente zu verwenden. Warum reaktive Form verwenden, wenn Sie eine Zweiwege-Bindung verwenden? Das würde bedeuten, dass die modellgetriebene Form völlig überflüssig ist. Wenn Sie dieses Problem mithilfe des modellgesteuerten Formulars lösen möchten, würde ich Folgendes vorschlagen:

Da Sie ein separates Objekt verwenden (record.priority), kann es nicht automatisch als der vorausgewählte Wert gebunden werden. Ich muss irgendwie eine Referenz erstellen. Also, wenn Sie ein Formular bauen können Sie dies tun:

this.myForm = this.fb.group({ 
    priority: [this.formModel.priorities.find(x => x.id == this.record.priority.id)] 
}); 

Und die Vorlage würde wie folgt aussehen:

<form [formGroup]="myForm"> 
    <select *ngIf="formModel" formControlName="priority"> 
    <option value="-1">Select priority</option> 
    <option *ngFor="let priority of formModel.priorities" 
     [ngValue]="priority" 
     [innerHtml]="priority.name"></option> 
    </select> 
</form> 

nun der Wert Objekt, das Sie aus dem Formular immer hält diesen Wert.

Wenn die record Async kommen, können Sie ein boolesches Flag setzen, um das Formular erst anzuzeigen, wenn die Werte festgelegt wurden. Oder Sie können zunächst ein leeres Formular erstellen und dann setValue() für die Formularsteuerung verwenden.

DEMO

EDIT: Bei näherer Betrachtung, dass Sie den Zustand haben wollen null zu setzen, wenn es keinen Wert für record.priority ist? Das kann auch gut in Form Kontrolle erfolgen:

priority: [this.record.priority ? this.formModel.priorities.find(x => x.id == this.record.priority.id) : null] 
+0

Mit diesem Code ist die richtige Option tatsächlich ausgewählt. Das Problem ist jetzt, wie kann ich irgendwelche Änderungen an 'record' widerspiegeln? 'record' ist eigentlich ein' @Input() 'dieser Komponente. – Bunnynut

+0

'this.record.priority = this.myForm.controls ['Priorität']. Value' funktioniert, aber es muss einen einfacheren Weg geben, hoffe ich. – Bunnynut

+0

Warum müssen Sie den Wert zu 'record' hinzufügen? Sie haben den Wert in dem Objekt, das von form erstellt wurde, warum nicht? :) ** ODER ** Brauchst du eigentlich die 'Aufzeichnung', um einige zusätzliche Dinge zu tun? Überdenken Sie vielleicht die reaktive Form und machen Sie eine Template-gesteuerte Form, weil wie gesagt, Zwei-Wege-Bindung wird abgeraten. Der springende Punkt ist, die Zweiwege-Bindung durch eine modellgetriebene Form zu ersetzen. Vielleicht ist Ihre Anforderung eher für eine Vorlage geeignet? Schwer zu sagen, nur basierend auf dieser Information :) – Alex

1

Try this:

<select *ngIf="formModel" [(ngModel)]="record.priority.id" formControlName="priority"> 
    <option value="-1">Select priority</option> 
    <option *ngFor="let priority of formModel.priorities" 
     [ngValue]="priority.id" 
     [innerHtml]="priority.name"></option> 
</select> 

[ngValue]="priority.id" und [(ngModel)]="record.priority.id" sollte auf den gleichen Wert zeigen, und es wird automatisch arbeiten,

Es besteht keine Notwendigkeit [selected]="priority.id == record.priority.id"

+0

Das funktioniert, aber wenn ich den 'record' auf dem Server poste, werden die Änderungen nicht in den geposteten Daten wiedergegeben, so dass die Priorität immer noch den alten Wert hat. Dies funktioniert auch für dieses spezifische Attribut, aber wie würde das ein anderes Attribut funktionieren? Wie kann ich ein Attribut in einer Bedingung hinzufügen oder weglassen? – Bunnynut

+1

Können Sie mir über Plunker zeigen? –

Verwandte Themen