Mat-Dialog在打开并第一次关闭后无法正确加载新视频

时间:2018-08-05 05:05:19

标签: angular typescript angular-material2

我有一个视频页面,其中显示了视频项目组件的列表,这些组件是指向vimeo api的链接。当您单击任何一个链接时,我都可以打开一个模态,显示正确的视频并可以播放。

我已经实现了向右/向左滚动箭头,可检查服务以确保videoservice阵列中有更多视频。视频之间的滚动很好用。问题是,当您关闭模式后,在视频列表页面上选择任何链接时,该模式就会弹出并加载其中已加载的LAST视频,而这不一定是您刚刚单击的视频项目链接上。

我正在竭尽所能破坏模式,方法是调用dialog.close(),dialog.closeAll(),并使MatDialogRef为null。没事。我几乎觉得这可能与以下事实有关:模态内部的数据是输入组件,但我对所有这些都不是很熟悉,并且对Angular还是陌生的。我正在使用Angular 5和“材质”对话框版本3。

这是我的视频项目组件。这些是从* ngFor循环中的父视频列表呈现的:

import {Component, Input, AfterViewInit} from '@angular/core';
import { MatDialog } from '@angular/material';

import { MediaDialogComponent } from '../../../../media-dialog/media-dialog.component';
import { SanitizerPipe } from '../../../../shared/sanitizer.pipe';
import { VideosService } from '../../../../videos.service';
import {Video} from '../../video.model';

@Component({
  selector: 'app-video-item',
  templateUrl: './video-item.component.html',
  styleUrls: ['./video-item.component.css']
})
export class VideoItemComponent implements AfterViewInit {
  @Input() video: Video;
  @Input() id: number;
  dialogConfig: {};

  constructor(
    private vService: VideosService,
    private sanitizer: SanitizerPipe,
    private dialog: MatDialog) {}

  ngAfterViewInit() {
    const url = this.sanitizer.transform(this.video.iframeObject.html);
    this.dialogConfig = {
      hasBackdrop: true,
      data: {
        media: this.video,
        url: url,
        id: this.id,
        title: this.video.title
      },
      autoFocus: true,
      panelClass: 'modal-box',
      backdropClass: 'backdrop',
      width: '400px',
      height: '300px',
      position: {
        top: '',
        bottom: '',
        left: '',
        right: ''
      }
    };
  }

  onShowVideo() {
   const url = this.sanitizer.transform(this.video.iframeObject.html);
   this.dialogConfig = {
    hasBackdrop: true,
    data: {
      media: this.video,
      url: url,
      id: this.id,
      title: this.video.title
    },
    autoFocus: true,
    panelClass: 'modal-box',
    backdropClass: 'backdrop',
    width: '400px',
    height: '300px',
    position: {
      top: '',
      bottom: '',
      left: '',
      right: ''
    }
  };
   const dialogRef = this.dialog.open(MediaDialogComponent, this.dialogConfig);
   this.vService.setDialog(dialogRef, this.dialog);
  }

}

这是视频项目模板:

<a (click)="onShowVideo()">
  <div class="row vid-list-row">
    <div class="col-xs-6">
      <img src="{{ video.thumbnailObject['urlWithBtn'] }}"
           alt="video thumb"
           width="250px"
           height="150px"
           class="img-thumbnail img-fluid.max-width: 100%"/>
    </div>
    <div class="col-xs-6">
      <h4>Title: </h4><h6>{{ video.title }}</h6>
      <h4>Author: </h4><h6>{{ video.authorName }}</h6>
    </div>
  </div>
  <hr>
</a>

这是我的media-dialog组件,它是模式内部使用的组件:

import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';

import { Subscription } from 'rxjs/Subscription';

import { Video } from '../body/videos/video.model';
import { SanitizerPipe } from '../shared/sanitizer.pipe';
import { VideosService } from '../videos.service';

@Component({
  selector: 'app-media-dialog',
  templateUrl: './media-dialog.component.html',
  styleUrls: ['./media-dialog.component.css']
})
export class MediaDialogComponent implements OnInit, OnDestroy {
  videoScrollSub: Subscription;
  hasPreviousVideo: boolean;
  hasNextVideo: boolean;
  url: any;
  title: string;
  safeUrls: any[];

  constructor(
    private vService: VideosService,
    private dialogRef: MatDialogRef<MediaDialogComponent>,
    public sanitizerPipe: SanitizerPipe,
    @Inject(MAT_DIALOG_DATA) public data: any) {}

  ngOnInit() {
    this.videoScrollSub = this.vService.videoScroll$.subscribe(
      (data: {video: Video, id: number}) => {
        if (data) {
          console.log('data: ', data);
          this.title = data.video.title;
          this.dialogRef.componentInstance.data.title = data.video.title;
          this.dialogRef.componentInstance.data.media = data.video;
          this.dialogRef.componentInstance.data.id = data.id;
          this.url = this.vService.safeUrls[data.id];
          this.dialogRef.componentInstance.data.url = this.url;
          this.setScrollValues();
        }
      }
    );
    this.url = this.dialogRef.componentInstance.data.url;
    this.title = this.dialogRef.componentInstance.data.title;
    this.setScrollValues();
  }

  ngOnDestroy() {
    this.videoScrollSub.unsubscribe();
  }

  onClose() {
    this.dialogRef.close();
    this.dialogRef = null;
    this.data = null;
    this.url = null;
    this.title = null;
    this.vService.destroyDialog();
  }

  onScroll(direction: string) {
    this.vService.onScrollVideo(direction, this.data.id);
  }

  setScrollValues() {
    this.hasPreviousVideo = this.data.id > 0 ? true : false;
    this.hasNextVideo = this.data.id < this.vService.videoBlobs.length - 1 ? true : false;
  }

}

这是媒体对话框模板:

<div class="top-outer">
  <button [mat-dialog-close] class="close-btn" (click)="onClose()">
    <i class="material-icons">close</i>
  </button>
</div>
<ng-container *ngIf="this.title">
    <h2 mat-dialog-title class="title">{{ this.data.title }}</h2>
</ng-container>
<mat-dialog-content *ngIf="this.url">  
    <iframe [src]="this.data.url"
    class="libcast_player"
    frameborder="0"
    scrolling="no"
    allowfullscreen="allowfullscreen"></iframe>
</mat-dialog-content>
<mat-dialog-actions>  
  <a
  *ngIf="this.hasPreviousVideo"
  class="btn-left"
  (click)="onScroll('previous')">
  <i  
  class="material-icons md-36">chevron_left</i></a> 
  <a
  *ngIf="this.hasNextVideo"
  class="btn-right"
  (click)="onScroll('next')">
  <i  
  class="material-icons md-36">chevron_right</i></a>
</mat-dialog-actions>

最后是我的视频服务:

import {HttpClient} from '@angular/common/http';
import {Injectable, OnInit} from '@angular/core';
import { MatDialogRef, MatDialog } from '@angular/material';
import { SafeResourceUrl } from '@angular/platform-browser';

import { BehaviorSubject } from 'rxjs';

import { Video } from './body/videos/video.model';
import { MediaDialogComponent } from './media-dialog/media-dialog.component';
import { SanitizerPipe } from './shared/sanitizer.pipe';

@Injectable()
export class VideosService implements OnInit {
  videoUrls: string[] = [
    'https://vimeo.com/269103891',
    'https://vimeo.com/106779077',
    'https://vimeo.com/110754599',
    'https://vimeo.com/96428643',
    'https://vimeo.com/80428769',
    'https://vimeo.com/26726819'
  ];
  videoBlobs: Video[] = [];
  safeUrls: SafeResourceUrl[];
  videoScroll$ = new BehaviorSubject<any>(null);
  currentDialog: MatDialogRef<MediaDialogComponent>;
  matDialog: MatDialog;
  currentConfig: {};

  constructor(
    private sanitizerPipe: SanitizerPipe,
    private http: HttpClient) {}

  ngOnInit() {}

  loadVideoList(): void {
    this.safeUrls = [];
    console.log('getting videos');
    for (const url of this.videoUrls) {
      this.http
        .get('https://vimeo.com/api/oembed.json?url=' + url)
        .subscribe(data => {
          if (data) {
            this.videoBlobs.push(
              new Video(
                data['title'],
                data['author_name'],
                data['html'],
                data['width'],
                data['height'],
                data['duration'],
                data['description'],
                data['thumbnail_url'],
                data['thumbnail_url_with_play_button'],
                data['thumbnail_width'],
                data['thumbnail_height'],
                data['video_id'],
                data['upload_date']
              )
            );
            const safeUrl = this.sanitizerPipe.transform(data['html']);
            this.safeUrls.push(safeUrl);
          }
        });
    }
  }

  setDialog(dialog: MatDialogRef<any>, matDialog: any) {
    this.currentDialog = dialog;
    this.matDialog = matDialog;
  }

  destroyDialog() {
    this.currentDialog = null;
    this.matDialog = null;
  }

  onScrollVideo(direction: string, index: number) {
    if (direction === 'previous') {
      if (index > 0) {
        index = index - 1;
        this.updateCurrentDialogRef(this.videoBlobs[index], index);
      } else {
        this.updateCurrentDialogRef(this.videoBlobs[index], index);
      }
    }
    if (direction === 'next') {
      if (index < this.videoBlobs.length - 1) {
        index = index + 1;
        this.updateCurrentDialogRef(this.videoBlobs[index], index);
      } else {
        this.updateCurrentDialogRef(this.videoBlobs[index], index);
      }
    }
  }

  updateCurrentDialogRef(video: Video, id: number) {
    this.videoScroll$.next({video: video, id: id});
  }

  getVideos(): Video[] {
    return this.videoBlobs;
  }

  getVideo(index: number): Video {
    return this.videoBlobs[+index];
  }

}

任何帮助将不胜感激。我读了一些有关刷新路由以清除所有模式实例的内容,但是那没有用。谢谢。

0 个答案:

没有答案