gpt4 book ai didi

javascript - Angular 2路由参数更改,但组件不重新加载

转载 作者:太空狗 更新时间:2023-10-29 18:32:03 25 4
gpt4 key购买 nike

所以,基本上我需要在 id 之后重新加载我的组件url 参数已更改。这是我的player.component.ts:

import {Component, OnInit, AfterViewInit} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
declare var jQuery: any;

@Component({
selector: 'video-player',
templateUrl: './player.component.html',
styleUrls: ['./player.component.less']
})

export class VideoPlayerComponent implements OnInit, AfterViewInit {
playerTop: number;
currentVideoId: number;

constructor(
private _route: ActivatedRoute,
private _router: Router
) {

}

ngOnInit(): void {
this._route.params.subscribe(params => {
this.currentVideoId = +params['id'];
console.log( this.currentVideoId );
this._router.navigate(['/video', this.currentVideoId]);
});
}

ngAfterViewInit(): void {
if (this.videoPageParams(this.currentVideoId)) {
console.log( "afterViewInit" );
let params = this.videoPageParams(this.currentVideoId);
let fakeVideoItemsCount = Math.floor(params.containerWidth / params.videoItemWidth);
this.insertFakeVideoItems( this.currentVideoId, fakeVideoItemsCount);
this.changePlayerPosition( params.videoItemTop );
}

}

videoPageParams( id ): any {
let videoItemTop = jQuery(`.videoItem[data-id="${id}"]`).position().top;
let videoItemWidth = jQuery('.videoItem').width();
let containerWidth = jQuery('.listWrapper').width();
return {
videoItemTop,
videoItemWidth,
containerWidth
};
}

changePlayerPosition( videoItemTop ): void {
this.playerTop = videoItemTop;
}

insertFakeVideoItems( id, fakeVideoItemsCount ): void {
let fakeVideoItemHTML = `<div class="videoItem fake"></div>`;
let html5playerHeight = jQuery('#html5player').height();
let videoItemIndex = jQuery(`.videoItem[data-id="${id}"]`).index() + 1;
let videoItemInsertAfterIndex;
let videoItemRow = Math.ceil(videoItemIndex / fakeVideoItemsCount);
let videoItemRowBefore = videoItemRow - 1;
if ( videoItemIndex <= 4 ) {
videoItemInsertAfterIndex = 0;
} else {
videoItemInsertAfterIndex = (videoItemRowBefore * fakeVideoItemsCount);
}
let videoItemInsertAfter = jQuery('.videoItem').eq(videoItemInsertAfterIndex);

for ( let i = 0; i < fakeVideoItemsCount; i++ ) {
$(fakeVideoItemHTML).insertBefore(videoItemInsertAfter);
}
jQuery(`.videoItem.fake`).css('height', html5playerHeight);

}

}

player.component.html:

<video
class="video"
preload="auto"
[attr.data-id]="currentVideoId"
src="">
</video>

<videos-list></videos-list>

videoList.component.html

<div class="videoItem" *ngFor="let video of videos" [attr.data-id]="video.id">
<a [routerLink]="['/video', video.id]">
<img [src]='video.thumbnail' alt="1">
</a>
</div>

所以当我点击 <a [routerLink]="['/video', video.id]">例如,在 videoList.component.html 中,它将路由更改为/video/10,但是 player.component.ts 中操作 DOM 的部分不会再次触发 - DOM 操作不更新

我试图通过 this._router.navigate(['/video', this.currentVideoId]); 手动导航到路线但不知何故它不起作用。

问题有什么方法可以在每次同一 URL 中的路由参数更改时运行操作 DOM 的函数?

最佳答案

DOM 不会更新,因为 ngOnInit 只被触发一次,所以即使您尝试从子节点“重新导航”回父节点,它也不会更新,因为父节点在任何时候都没有从 DOM 中移除。

解决这个问题的一个选择是,您可以使用 Subject,当路由发生时,让我们将选择的视频 ID 发送给父级,父级订阅更改并执行您告诉的任何事情它要做的,意味着调用将更新 DOM 的函数,所以您可能想要重新执行的是内部 ngOnInitngAfterViewInit

您提到您曾尝试使用

this._router.navigate(['/video', this.currentVideoId])

让我们来看看。可能有一些触发功能的点击事件。假设它看起来像下面这样,我们将在剧中添加主题

navigate(id) {
VideoPlayerComponent.doUpdate.next(id)
this._router.navigate(['/video', this.currentVideoId])
}

让我们在您的父级中声明Subject,并订阅更改:

public static doUpdate: Subject<any> = new Subject();

然后在构造函数中让我们订阅更改...

constructor(...) {
VideoPlayerComponent.doUpdate.subscribe(res => {
console.log(res) // you have your id here
// re-fire whatever functions you need to update the DOM
});
}

关于javascript - Angular 2路由参数更改,但组件不重新加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42114585/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com