簡體   English   中英

Angular 2父組件從子組件丟失輸入綁定

[英]Angular 2 Parent Component Losing Input Binding from Child Component

我正在使用一個父組件,該父組件引用了在Angular 2中播放音頻文件的子組件。最初,我正在向音頻文件傳遞_audioState的輸入變量,該變量包含字符串值“ Listen”。 單擊音頻按鈕后,音頻文件播放完畢后,此值將更改為“正在播放”,然后變為“重播”。 這些字符串值更改發生在音頻子組件中。

當在父組件中單擊具有nextAudio函數的按鈕時,我想將_audioState重新分配回“ Listen”,但是一旦子組件更改了該值,輸入綁定就不會在父中起作用。

我仍在學習Angular 2,並且不確定使此工作正常的最佳方法。 我感謝任何建議。 我的代碼如下。

父組件:

 @Component({
    selector: 'parent-component',
    template: ' <div>
                    <button (click)="nextAudio()"></button>
                    <audio-button [audioPath]="_audioPath"  
                    [audioSrc]="_audioCounter" [audioState]="_audioState">          
                    </audio-button>
                </div>',
    styleUrls: ['./parent-component.less']
})

export class ParentComponent {
 _audioPath: string = "../audio/";
 _audioCounter: number = 1;
 _audioState: string = "Listen";

  nextAudio(): void{
    this._audioCounter = this._audioCounter + 1;
    this._audioState = "Listen";
  }  
}

子組件:

@Component({
    selector: 'audio-button',
    template: '<button (click)="playSound()"><i class="fa fa-volume-up"></i>    
    {{audioState}}</button>',
    styleUrls: ['./audio-button.component.less']
})
export class AudioButtonComponent {
    @Input() audioPath: string;
    @Input() audioSrc: string;
    @Input() audioState: string;

playSound(): void {
    let sound: any = new Audio(this.audioPath + this.audioSrc + ".mp3");
    sound.play();
    this.audioState = "Playing";
    sound.addEventListener('ended', () => {
        this.audioState = "Replay";
    }, false)

    event.preventDefault();
   }
}

有幾種方法可以做到這一點,包括

1.(命令)使用ngrx / store

參考文獻

將具有NgRx / Store的Redux添加到Angular(2+)–第1部分Oren Farhi

2. EventEmitter

例如,

@Component({
selector: 'parent-component',
template: `<div>
                Current state : {{_audioState}}
                <hr />
                <audio-button [audioPath]="_audioPath"
                [audioSrc]="_audioCounter" [audioState]="_audioState"
                (emit-status)="updateStatus($event)"
                >
                </audio-button>
            </div>`
})

export class ParentComponent {
  _audioPath: string = "../audio/";
  _audioCounter: number = 1;
  _audioState: string = "Listen";

  nextAudio(): void{ 
    this._audioCounter = this._audioCounter + 1;
    this._audioState = "Listen";
  }

  private updateStatus(status:string){
    this._audioState= status;
  }
}

import { Component, OnInit, Input, Output, EventEmitter } from           '@angular/core';

@Component({
   selector: 'audio-button',
   template: `<button (click)="playSound()"><i class="fa fa-volume-up"></i>
{{audioState}}</button>`,
})

export class AudioButtonComponent {
  @Input() audioPath: string;
  @Input() audioSrc: string;
  @Input() audioState: string;
  @Output('emit-status') emitStatus = new EventEmitter<any>();


  playSound(): void {
    //...

    //emit data to parent
    this.emitStatus.emit("playing");
  }
}

3. ViewChild

@Component({
   selector: 'parent-component',
   template: `<div>
            Current state : {{audioBtn.audioState}}
            <hr />
            <audio-button [audioPath]="_audioPath"
            [audioSrc]="_audioCounter" [audioState]="_audioState"
            (emit-status)="updateStatus($event)"
            >
            </audio-button>
        </div>`
})

export class ParentComponent {
    @ViewChild(AudioButtonComponent) audioBtn: AudioButtonComponent;
}

export class AudioButtonComponent {
   //...
  @Input() audioState: string;
  playSound(): void {
     //...
     this.audioState = "playing";
  }
}

結果

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM