2017-06-13 9 views
1

は、ここに私のコンポーネントである:私は入力に名前を変更し、その後、私は保存ボタンを押していますとthis.goodが良い変更されませんRxJSが角4のコンポーネントに小道具を正しく渡す方法は?

@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; 
    } 
} 

。それはコンポーネントに渡されたように、古いgoodです。

問題をデバッグし始めました。私はonInputハンドラを追加しました。 this.good.name = $event.target.value;私はコンソールにこのエラーが出ます:ここで

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

は、コンポーネントの使用方法である:ここで

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

は、私がこのコンポーネントのデータを受信する方法である:

私はこの命令を実行する際にことがわかりました
/*…*/ 
selectedGood$: Observable<Good>; 

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

コンテナコンポーネントの完全なコードは次のとおりです。here

思考:Observableは不変構造を返すため、問題があると思います。私はそれが完全に悪い考えだとは思わないが、それをどう扱うか?

私はそこで同じ行動を取ろうとしています:http://plnkr.co/edit/gdxEcSvC0v6JwoLEZDkJ?p=preview。それは再現されません。私はこれがそうだと思う

私の問題を解決するには?私はそのようなエラーを取得したくありません。私が保存を押すと、this.goodに変異オブジェクトが含まれます。これを達成する方法は?

+0

は、あなたはこれを解決しましたか? –

+0

わかりません。私はtodolistの反応型について研究しています。彼らもそこに助けてくれると言う人もいます。あなたの提案は、私が思うように答えの一つです。私がより多くの変種を得るなら、私はあなたの答えを改善します。時間をください。 –

答えて

3

プレゼンテーションコンポーネントに元のオブジェクトのコピーを作成し、保存時にそのコピーの値を出力することができます。突然変異したオブジェクトを放出した後、あなたが送るアクションはそれをペイロードとして保存しなければならず、リデューサーは古いオブジェクトを突然変異したものに置き換える必要があります。それは私が私のプレゼンテーションコンポーネントで使用し、少なくともアプローチです:)

例えば:

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

コードの例はありますか?それはベストプラクティスですか?他の方法を試しましたか? –

+0

ここで見てください、同様のアプローチが使用されます:http://onehungrymind.com/build-better-angular-2-application-redux-ngrx/ –

+0

はい、このアプローチは明らかに機能します...私は今でも同様のアプローチを持っていますが実装されていますngOnChangesで。それは2つの特性を持つことにうんざりしています。 1つは入力で、もう1つはローカルコピーです。それはベストプラクティスですか?私がこのように行くと、コンポーネントの本体はより汚れになります。もちろん、あなたの答えに感謝します。 Upvote –

関連する問題