2017-06-13 2 views
1

Hier ist meine Komponente:Wie können Requisiten korrekt an eine Komponente mit RxJS in Angular 4 übergeben werden?

@Component({ 
    selector: 'bc-goods-detail', 
    template: ` 
    <span>good id: {{good?.id}}</span> 
    <input [value]="good?.name" (input)="onInput($event)" /> 
    <button (click)="onClick()">Save</button> 
    `, 
    styles: [] 
}) 
export class GoodsDetailComponent { 
    @Input() good: Good; 
    @Output() save = new EventEmitter<Good>(); 

    onClick() { 
    this.save.emit(this.good); 
    } 

    onInput ($event) { 
    this.good.name = $event.target.value; 
    } 
} 

Wenn ich den Namen in der Eingabe ändern und dann speichern Taste Ich gedrückt this.good nicht verändert wird gut. Es ist alt good, wie es an die Komponente weitergegeben wurde.

Ich begann das Problem zu debuggen. Ich fügte onInput Handler hinzu. Ich fand, dass, wenn ich diese Anweisung tun: this.good.name = $event.target.value; ich diesen Fehler in der Konsole erhalten:

ERROR TypeError: Cannot assign to read only property 'name' of object '#<Object>' 
    at GoodsDetailComponent.webpackJsonp.435.GoodsDetailComponent.onInput (goods-detail.ts:24) 

Hier ist die Nutzung der Komponente:

<bc-goods-detail 
    [good]="selectedGood$ | async" 
    (save)="onSave($event)" 
></bc-goods-detail> 

Hier ist, wie ich Daten für diese Komponente erhalten:

/*…*/ 
selectedGood$: Observable<Good>; 

constructor(private store: Store<fromRoot.State>) { 
    /*…*/ 
    this.selectedGood$ = store.select(fromRoot.getGoodSelectedEntity); 
} 

Hier ist der vollständige Code der Container-Komponente: here.

Gedanken: Ich denke, das Problem ist, weil Observable unveränderliche Struktur zurückgibt. Ich denke nicht, dass es eine total schlechte Idee ist, sondern wie man damit umgeht.

Ich versuche, dasselbe Verhalten dort zu erhalten: http://plnkr.co/edit/gdxEcSvC0v6JwoLEZDkJ?p=preview. Es reproduziert nicht. Ich denke das ist weil

Wie mein Problem zu lösen? Ich will keinen solchen Fehler bekommen. Wenn ich Speichern drücke, möchte ich this.good mutiertes Objekt enthalten. Wie erreiche ich das?

+0

Haben Sie dieses Problem gelöst? –

+0

Nicht sicher. Ich habe über reaktive Formen in meinem Todolist recherchiert. Manche sagen, dass sie auch dort helfen können. Ihr Vorschlag ist eine der Antworten, wie ich denke. Wenn ich mehr Varianten bekomme, werde ich Ihre Antwort verbessern. Gib mir ein wenig Zeit. –

Antwort

3

Sie könnten eine Kopie des ursprünglichen Objekts in Ihrer Präsentationskomponente erstellen und den Wert dieser Kopie beim Speichern ausgeben. Nach dem Auslösen des mutierten Objekts sollte die Aktion, die Sie versenden, als Nutzlast gespeichert werden, und der Reduzierer sollte dafür sorgen, dass das alte Objekt durch das mutierte ersetzt wird. Das ist zumindest der Ansatz, den ich in meiner Präsentation Komponenten verwenden :)

Zum Beispiel:

export class GoodsDetailComponent { 
    private _original: Good; 
    goodClone: Good; // use this inside of the component template 
    @Input('good') 
    get good(){return this.goodClone;} 
    set good(value: Good){ 
    this.goodClone= //generate a clone of the object 
    this._original = value; 
    } 

    @Output() 
    save = new EventEmitter<Good>(); 

    onClick() { 
    this.save.emit(this.goodClone); 
    } 
} 
+0

Haben Sie Beispiele für den Code? Ist es die beste Praxis? Hast du irgendwelche anderen Ansätze versucht? –

+0

werfen Sie einen Blick hier, ein ähnlicher Ansatz wird verwendet: http://onehungrymind.com/build-better-angular-2-application-redux-ngrx/ –

+0

Ja, dieser Ansatz funktioniert offensichtlich ... Ich habe ähnliche Ansatz jetzt aber implementiert mit ngOnChanges. Nun, es sieht schrecklich aus, zwei Eigenschaften zu haben. Einer ist eine Eingabe und ein anderer eine lokale Kopie. Ist es die beste Praxis? Der Körper wird immer dreckiger, wenn ich diesen Weg gehe ... Das ist nicht cool. Natürlich danke für deine Antwort. Upvote –

Verwandte Themen