繁体   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