Angular 数据更改时重新创建组件

Angular 数据更改时重新创建组件,angular,typescript,rxjs,rxjs5,Angular,Typescript,Rxjs,Rxjs5,好吧,这个问题似乎有很多答案,但我还不能理解我应该做什么 我当前有一个子组件,当有人从另一个子组件单击播放按钮时,该子组件正在创建。这是通过一个服务实现的,该服务与我的父级共享数据,然后父级传递数据并创建我的子音频播放器组件。我遇到的问题是,如果用户导航到另一个页面并单击以播放该页面上的音频,则旧音频仍然存在,而新音频不会启动 是否有一个生命周期挂钩或方法可以用来销毁旧的音频组件并创建新的音频onclick 信息框-单击播放按钮时发生初始激活的位置 export class InfoBoxCom

好吧,这个问题似乎有很多答案,但我还不能理解我应该做什么

我当前有一个子组件,当有人从另一个子组件单击播放按钮时,该子组件正在创建。这是通过一个服务实现的,该服务与我的父级共享数据,然后父级传递数据并创建我的子音频播放器组件。我遇到的问题是,如果用户导航到另一个页面并单击以播放该页面上的音频,则旧音频仍然存在,而新音频不会启动

是否有一个生命周期挂钩或方法可以用来销毁旧的音频组件并创建新的音频onclick

信息框-单击播放按钮时发生初始激活的位置

export class InfoBoxComponent implements OnInit {
  ...

  activateAudioPlayer(session) {
    this.newAudioService.newAudio(session)
  }
}
新的音频服务

export class NewAudioService {
  newActiveAudioSource: Subject<string> = new Subject<string>();

  newAudio(session) {
    this.newActiveAudioSource.next(session);
  }

  newActiveAudio$ = this.newActiveAudioSource.asObservable();
}
导出类NewAudioService{
newActiveAudioSource:Subject=新主题();
新音频(会话){
this.newActiveAudioSource.next(会话);
}
newActiveAudio$=this.newActiveAudioSource.asObservable();
}
前端组件-信息盒和音频播放器的父组件

@Component({ 
   template: `<audio-player *ngIf='newActiveAudio' [newActiveAudio]='newActiveAudio'></audio-player>`,
})

export class FrontendComponent implements OnInit {

  ...

  ngOnInit() {
    this.sub = this.newAudioService.newActiveAudio$.subscribe(
      newActiveAudio => {
        this.newActiveAudio = newActiveAudio;
      });
  }

  ngOnDestroy() {
    // prevent memory leak when component destroyed
    this.sub.unsubscribe();
  }
}
@组件({
模板:``,
})
导出类FrontendComponent实现OnInit{
...
恩戈尼尼特(){
this.sub=this.newAudioService.newActiveAudio$.subscribe(
newActiveAudio=>{
this.newActiveAudio=newActiveAudio;
});
}
恩贡德斯特罗(){
//防止组件损坏时内存泄漏
此.sub.取消订阅();
}
}

一种可能的方法是设置
this.newActiveAudio=false
然后让Angle使用
setTimeout()
更新视图,然后为
newActiveAudio
设置新值:

this.sub = this.newAudioService.newActiveAudio$.subscribe(newActiveAudio => {
    this.newActiveAudio = false;
    setTimeout(() => {
        this.newActiveAudio = newActiveAudio;
    });
});

找到了一个小技巧。将您的元素放在一个元素数组中,并使用trackBy创建ngFor

 <component *ngFor="let o of [object]; trackBy: trackByObjectProperty">
        </component>


这里有一个小指令,当
值更改时,它会重新创建视图:

import {
  Directive,
  EmbeddedViewRef,
  Input,
  OnChanges,
  SimpleChanges,
  TemplateRef,
  ViewContainerRef
} from '@angular/core';

@Directive({
  selector: '[wRecreateViewKey]'
})
export class RecreateViewDirective implements OnChanges {
  @Input('wRecreateViewKey') key: any;

  viewRef: EmbeddedViewRef<any>;

  constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) {}

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.key) {
      if (this.viewRef) {
        this.destroyView();
      }

      this.createView();
    }
  }

  private createView() {
    this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
  }

  private destroyView() {
    this.viewRef.destroy();
    this.viewRef = null;
  }
}

导入{
指令,
嵌入式ViewRef,
输入,
一旦改变,
SimpleChanges,
TemplateRef,
ViewContainerRef
}从“@angular/core”开始;
@指示({
选择器:“[wRecreateViewKey]”
})
导出类RecreateViewDirective实现OnChanges{
@输入('wRecreateViewKey')键:任意;
viewRef:嵌入式viewRef;
构造函数(私有templateRef:templateRef,私有viewContainer:ViewContainerRef){}
ngOnChanges(更改:SimpleChanges):无效{
if(changes.key){
if(this.viewRef){
这个.destroyView();
}
这是createView();
}
}
私有createView(){
this.viewRef=this.viewContainer.createEmbeddedView(this.templateRef);
}
私有视图(){
this.viewRef.destroy();
this.viewRef=null;
}
}
用法示例:



InfoBoxComponent
是多次创建然后销毁的组件,这也会销毁音频元素?InfoBoxComponent是在我的frontendComponent中创建的,audioplayerComponent是在单击InfoBoxComponent中的按钮时创建的。我这样做是为了让用户能够浏览我的网站,并且在找到他们想要播放的另一个选择之前,仍然可以播放音频。问题是,一旦audioPlayerComponent初始化,我需要一种方法来销毁它,并使用不同的数据重新创建它。抱歉,如果我的原始问题不清楚。只是想知道这是否有效:
this.sub=this.newAudioService.newActiveAudio$.subscribe(newActiveAudio=>{this.newActiveAudio=null;this.newActiveAudio=newActiveAudio;})
然而,我想说的是,你应该在
音频播放器的内部使用
OnChange
,卸载(停止/暂停/销毁)旧的音频对象,然后加载新的。OnChange也可以!我现在唯一的问题是因为音频元素是在js中创建的,当另一个元素被创建时,它会继续播放!它带来的唯一问题是旧音频继续播放,但我认为这是因为我正在动态添加音频文件。我确信我可以在audioplayer的单元上杀死audio元素。但我不确定仅仅从DOM中删除该元素会阻止它播放。。。