我有一个视频页面,其中显示了视频项目组件的列表,这些组件是指向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];
}
}
任何帮助将不胜感激。我读了一些有关刷新路由以清除所有模式实例的内容,但是那没有用。谢谢。