2017-02-08 10 views
2

Итак, в основном мне нужно перезагрузить мой компонент после того, как был изменен параметр URL-адреса id. Это мой player.component.ts:Угловой 2 изменения параметров маршрута, но компонент не перезагружается

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.comp onent.html он изменяет маршрут к/video/10 например, но часть от player.component.ts, которая управляет DOM, не запускается снова - DOM-манипуляция не обновляется.

Я попытался вручную перейти к маршруту через this._router.navigate(['/video', this.currentVideoId]);, но каким-то образом он не работает.

ВОПРОС Есть ли способ запускать функции, которые манипулируют DOM при каждом изменении параметра маршрута по тому же самому URL?

+0

Не могли бы уделить ур код, где вы читаете routeParams? – Smit

+0

@ Считайте, что вы подразумеваете под '' чтением''? '' this._route.params.subscribe (params => { this.currentVideoId = + params ['id']; console.log (this.currentVideoId); this._router.navigate (['/ video', this.currentVideoId]); }); '' эта часть, где я читаю route param – lomboboo

+0

Почему вы перенаправляете? 'this._router.navigate (['/ video', this.currentVideoId]); ' – Smit

ответ

1

DOM не будет обновляться, так как ngOnInit запускается только один раз, поэтому он не будет обновляться, даже если вы попытаетесь «переоткрыть» родительский элемент от дочернего элемента, поскольку родительский объект не был удален из DOM в любой точке ,

Один из вариантов решения этой проблемы состоит в том, что вы можете использовать Subject, что, когда происходит маршрутизация, давайте отправим выбранный идентификатор видео в родительский, который подписался на это изменение и сделает все, что вы ему скажете, что означает вызов функции, которые будут обновлять DOM, так что, вероятно, что вы хотите повторно выполняется это внутри ngOnInit и ngAfterViewInit

вы упомянули, что вы пытались использовать

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

так что давайте посмотрим на это. Вероятно, есть событие click, которое запускает функцию. Скажем, это выглядит следующим образом, мы просто добавить тему в пьесе

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 
    }); 
}