簡體   English   中英

我如何讓 @vimeo/player 在我的 Angular2/Typescript 項目上工作?

[英]How do I get @vimeo/player to work on my Angular2/Typescript project?

問題:

我如何讓@ vimeo/player 處理我的 Angular2/Typescript 項目(特別是 Ionic2)?

說明:

試圖讓 vimeo播放器與 Angular2/Typescript 一起工作。

npm install --save @vimeo/player

根據他們的文檔,可以像這樣使用庫:

如果您使用的是像 webpack 或 rollup 這樣的模塊打包器,導出的對象將是 Player 構造函數(與它附加到 window.Vimeo 的瀏覽器不同):

import Player from '@vimeo/player';

const player = new Player('handstick', {
    id: 19231868,
    width: 640
});

player.on('play', function() {
    console.log('played the video!');
});

這看起來非常有前途! 但不起作用。

我試過的:

我已經安裝了@vimeo/player @types/vimeo__player @vimeo/player@types/vimeo__player我在我的 Ionic2 應用程序中創建了一個播放器組件。

玩家.ts:

import {Component, ViewChild} from '@angular/core';
import {NavController} from "ionic-angular/index";

//noinspection TypeScriptCheckImport,TypeScriptCheckImport
import Player from "@vimeo/player";


@Component({
  selector: 'player-component',
  templateUrl: 'player.html'
})
export class PlayerComponent {

  @ViewChild('player_container') playerContainer;
  private player: Player;

  constructor(public navCtrl: NavController){}

  ngAfterViewInit() {
    // child is set
    this.player = new Player(this.playerContainer);
    console.log(Player);
  }

}

我使用 view child,但我也嘗試過使用元素的 ID。

播放器.html

<div #player_container></div>

並得到以下錯誤:

未捕獲(承諾):類型錯誤:您必須傳遞有效元素或有效 ID。 Player@ http://localhost:8100/build/main.js:102846:32 ngAfterViewInit@ http://localhost:8100/build/main.js:74715:80 callProviderLifecycles@ http://localhost:8100/build/ main.js:11417:33 callElementProvidersLifecycles@ http://localhost:8100/build/main.js:11392:35 callLifecycleHooksChildrenFirst@ http://localhost:8100/build/main.js:11376:47 checkAndUpdateView@ http:// /localhost:8100/build/main.js:12408:36 callWithDebugContext@ http://localhost:8100/build/main.js:13462:47 detectChanges@ http://localhost:8100/build/main.js:10474 :81 _viewAttachToDOM@ http://localhost:8100/build/main.js:43884:53 _transition@ http://localhost:8100/build/main.js: 43976 :34 onInvoke@ http://localhost:8100/ build/main.js:4406:43 run@ http://localhost:8100/build/polyfills.js:3:4146 http://localhost:8100/build/polyfills.js:3:13734 onInvokeTask@ http:// /localhost:8100/build/main.js:4397:47 runTask@ http://localhost:8100/build/polyfills.js:3:4841 o@ http://localhost:8100/build/polyfills.js:3 :1898 invoke@ http://localhost: 8100/build/polyfills.js:3:10674

如您所見,它可以編譯但在運行時崩潰。

@types/vimeo__player似乎還沒有完成,甚至在我導入@vimeo/player時似乎都沒有注意到

github 上關於 vimeo__player問題似乎表明這是真的。

看起來模塊解析正確地將其解析為 JS 模塊,但這只是因為它沒有首先找到類型。 你確定你正確地包含了這些類型嗎? --listFiles 會告訴你它是否包含在內。

附加功能:

發布在 Vimeo 的 github 播放器頁面上打開。

您的問題不是由@types/vimeo__player引起的,也與您的構建系統/配置無關。

TypeScript 類型定義從不、從不從不影響運行時的行為。 即使編譯時錯誤除了在控制台中顯示紅色之外沒有其他影響,JavaScript 仍然會被發出。

查看您獲得的堆棧跟蹤,我們還可以說Player已被有效導入,並且由於您說沒有編譯時錯誤,因此在構建方面一切正常。

事實上,錯誤說明了一切: TypeError: You must pass either a valid element or a valid id. .

Player說它需要一個HTMLElement

問題是,您正在使用來自 Angular 的@ViewChild() 當您查詢本機元素時,此裝飾器將返回一個包裝器。 此包裝器屬於ElementRef類型,並具有一個名為nativeElement的屬性,其中包含原始 DOM 元素。

所以不要這樣做:

this.player = new Player(this.playerContainer);

這樣做:

this.player = new Player(this.playerContainer.nativeElement);

但是您現在可能會想“為什么 TypeScript 沒有產生類型錯誤,因為我沒有傳遞原生元素?” . 這是個好問題,我沒有足夠的數據可以確定,但我認為您的導入可能不正確。

而不是:

//noinspection TypeScriptCheckImport,TypeScriptCheckImport
import Player from "@vimeo/player";

你能嘗試這樣做嗎?

import { Player } from '@vimeo/player';

查看 .d.ts 文件,看起來 Player 是一個命名導出。 但你是對的,@vimeo/player 的類型定義不完整,或者與 JavaScript 庫不同步。 您應該意識到 TypeScript 中的這類問題,盡管這種情況不會每天發生 ;)

對於標准項目,此導入語句有效。

import * as Player from "@vimeo/player/dist/player.js";

如果您的 ViewChild 未定義(由於延遲加載等),您可以嘗試以下操作:

  • ViewChild ren而不是 ViewChild;
  • 在運行代碼之前等待 DOM 可用;

代碼:

import { Component, ViewChildren } from '@angular/core';
import Player from "@vimeo/player";


@Component({
  selector: 'player-component',
  templateUrl: 'player.html'
})
export class PlayerComponent {

  private player: Player;
  @ViewChildren('player_container') playerContainer;

  ngAfterViewInit() {
    /* wait DOM be available */
    this.playerContainer.changes.subscribe(item => {
        if (this.playerContainer.length) {
            /* DOM AVAILABLE */
            this.player = new Player(this.playerContainer.first.nativeElement);

            this.player.on('play', function() {
                console.log('played the video!');
            });

            this.player.getVideoTitle().then(function(title) {
                console.log('title:', title);
            });
        }
    })
  }
}

根據他們的文檔

當庫加載時,它將掃描您的頁面以查找具有 Vimeo屬性的元素。 每個元素必須至少有一個data-vimeo-iddata-vimeo-url屬性,以便自動創建嵌入。

所以基本上它需要一個帶有“data-vimeo-id”屬性或“data-video-url”屬性的div標簽,並在調用播放器的構造函數之前分配有效值。

所以您可以使用屬性綁定將視頻 id(到 data-vimeo-id)或視頻 url(到 data-video-url)分配給模板文件中的 div 標簽。

 <div [attr.data-vimeo-id]="videoId"> </div>

並將要嵌入的視頻的視頻 ID 分配給 Typescript 文件(在 ngOninit 中)中的變量“videoId”。 在這種情況下,同樣可以用 url 完成 [attr.data-vimeo-url]="videoUrl";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM