向子级传递道具的角度未更新

cbu*_*ler 3 angular

我试图将一个对象作为道具传递给子组件。该对象以 null 开始,并在用户从列表中选择项目时设置。奇怪的是,该对象第一次设置正确,但之后就没有了。

这是我的父组件:

@Component({
  selector: 'my-app',
  template: `
  <div>
    <search-bar (submitted)="onSearch($event)"></search-bar>
    <div>
      <video-detail [video]="selectedVideo"></video-detail>
      <video-list [videos]="videos" [onVideoSelect]="onVideoSelect" ></video-list> 
    <div>  
  </div>
`
})     
export default class AppComponent {
  videos = [];
  selectedVideo = null;

  constructor(private youtube: YoutubeService) { }

  onSearch(searchTerm: string) {
    this.youtube.search(searchTerm).subscribe((response) => {
      this.videos = response.items;
      this.selectedVideo = response.items[0];
    });

  }

  // called when the user clicks an item
  onVideoSelect(video: object) {
    this.selectedVideo = video;
  }
}
Run Code Online (Sandbox Code Playgroud)

子组件:

const { Component, Input } = ng.core;
const { DomSanitizer } = ng.platformBrowser;

@Component({
  selector: 'video-detail',
  template: 
  `
    <ng-container *ngIf="video; else loading">
            <div>
                <div>
                    <iframe title="video player" [src]="getVideoSrc()"></iframe>
                </div>
                <div>
                    <h4 [innerHTML]="video.snippet.title"></h4>
                    <p [innerHTML]="video.snippet.description"></p>
                </div>
            </div>
        </ng-container>
   <ng-template #loading>
     <div>
       No Video Selected.
     </div>
   </ng-template>
  `
})
export default class VideoDetailComponent { 
    @Input() video = null;

  constructor(public sanitizer: DomSanitizer) { }

  getVideoSrc() {
    const videoSrc = this.sanitizer.bypassSecurityTrustResourceUrl(`https://www.youtube.com/embed/${this.video?.id?.videoId}`);
    return videoSrc;
  }
}
Run Code Online (Sandbox Code Playgroud)

知道我做错了什么吗?

Jam*_*mes 5

当您将对象传递@Inputs()给子对象时,Angular 仅在对象引用发生更改时才开始更改检测。

因此,当您更新对象时,它需要是一个新的引用,以便您的子组件对其进行操作。

尝试使用

this.selectedVideo = Object.assign({}, response.items[0]);
Run Code Online (Sandbox Code Playgroud)

这将每次创建一个新对象,因此 Angular 将拾取更改。