Утилизация URL-адресов вызывает обновление встроенного видео YouTube

У меня проблема с моим приложением AngularJS 2 (я использую RC5 версию AngularJS 2). Кажется, что очищенный URL-адрес запускает обнаружение изменений, которое затем обновляет div ниже, несмотря на отсутствие изменений в состоянии моего компонента.

С точки зрения пользователя это проявляется как перезагрузка видео во время воспроизведения.

Итак, в моем представлении компонентов у меня есть:

<div *ngIf="isVideo(item)">
   <iframe [src]="getTrustedYouTubeUrl(item)" scrolling="no" frameborder="0" allowfullscreen></iframe>          
</div>

Реализация указанной выше функции в коде компонента:

getTrustedYouTubeUrl(linkedVideo:LinkedVideoModel) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(linkedVideo.video.url);
}    

В отладчике я вижу, что div часто обновляется, что-то срабатывает в ракурсе AngularJS 2.

Проблема исчезнет, ​​если я заменил фрагмент HTML выше на жестко закодированный URL:

<div *ngIf="isVideo(item)">
   <iframe src="<hardcoded youtube url here>" scrolling="no" frameborder="0" allowfullscreen></iframe>          
</div> 

Таким образом, я подозреваю, что причиной этого является сатинирование URL.

Может ли кто-нибудь указать мне в правильном направлении? Рабочий пример встроенных видеороликов YouTube, имеющих свой URL-адрес, привязанный к свойству на компоненте, может быть?

Ответ 1

Выяснил это.

Для всех, кого это интересует. Проблема заключалась в использовании этой функции в моем html

   [src]="getTrustedYouTubeUrl(item)"

Эффект перезагрузки исчез, как только я изменил код, чтобы вычислить безопасный URL-адрес, когда данные загружены в мою службу, и изменил привязку iframe к этому

    <iframe [src]="item.video.safeUrl" scrolling="no" frameborder="0" allowfullscreen></iframe>    

Обратите внимание, что я теперь привязываюсь к свойству.

Ответ 2

Я бы попытался использовать его с чистый канал

Angular выполняет чистый канал только тогда, когда он обнаруживает чистое изменение в входное значение. Чистым изменением является либо изменение примитивного ввода значение (String, Number, Boolean, Symbol) или ссылка на объект (Дата, Массив, Функция, Объект).

Труба может выглядеть как (RC.6). Вместо DomSanitizationService вместо DomSanitizationService используется DomSanitizer):

@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
  constructor(private sanitizer: DomSanitizer) {}
  transform(url) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}

И используйте его как:

<iframe [src]="url | safe" frameborder="0" allowfullscreen></iframe> 

Пример плунжера (попробуйте нажать кнопку)

Ответ 3

Вы можете сохранить свое оригинальное решение и просто использовать changeDetection: ChangeDetectionStrategy.OnPush

<div *ngIf="isVideo(item)">
   <iframe [src]="getTrustedYouTubeUrl(item)" scrolling="no" frameborder="0" allowfullscreen></iframe>          
</div>

Ответ 4

Объедините предыдущие ответы, чтобы заставить его работать следующим образом:

component.ts(только соответствующие части)

import { DomSanitizer } from '@angular/platform-browser';

constructor( 
  private sanitizer: DomSanitizer   
) {
  this.sanitizer = sanitizer;
}

ngOnInit() {
 this.getTrustedUrl('http://someUrl');
}

getTrustedUrl(url:any){ 
 this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
}

template.html

<iframe      
  [src]='this.safeUrl'>
</iframe>