onYouTubeIframeAPIReady没有在angular2 web应用程序上触发
我正在使用angular 2,typescript和YouTube API构建一个Web应用程序,以便在用户登录后将播放器添加到页面中.
因此,一旦登录,该应用程序将加载以下组件: export class MyComponent implements OnInit { myService: MyService; constructor( private _myService: MyService ) { this.myService = _myService; } ngOnInit() { this._myService.loadAPI(); } } 组件html包含以下标记: <iframe id="player" type="text/html" width="640" height="360" src="http://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1" frameborder="0" allowfullscreen></iframe> 最后,该服务具有以下内容: player: YT.Player; loadAPI(){ var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag,firstScriptTag); console.log('API loaded'); // this is shown on the console. } onYouTubeIframeAPIReady(){ this.player = new YT.Player('player',{ events: { 'onReady': this.onPlayerReady,'onStateChange': this.onPlayerStateChange } }); console.log('youtube iframe api ready!'); // this is never triggered. } onPlayerReady(event){ event.target.playVideo(); } onPlayerStateChange(status){ console.log(status.data); } 我已经读过API自动调用函数“onYouTubeIframeAPIReady”,所以我想知道我应该做些什么来让它正常工作.
您需要在全局对象上定义您的函数onYouTubeIframeAPIReady.这与JavaScript的链接答案完全相同.
接下来是这里所有100%的JavaScript内容,通过其JavaScript性质的超集适用于TypeScript. 如果您正在使用模块(通常是Angular 2应用程序的情况),那么您的代码将被隔离,并且默认情况下不会在全局范围内执行.这意味着为了定义全局,我们需要获得对全局对象的引用.在浏览器中,这非常简单,因为窗口指的是全局(除非它被遮蔽). 你需要写的东西非常简单.它本质上是 window.onYouTubeIframeAPIReady = function () { ... }; 这意味着获取当前的代码,如下所示 export default class YouTubeService { ... loadAPI() { var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag,firstScriptTag); console.log('API loaded'); // this is shown on the console. } onYouTubeIframeAPIReady() { } } 并将其改为此 export default class YouTubeService { ... loadAPI() { window.onYouTubeIframeAPIReady = function () { }; var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag,firstScriptTag); console.log('API loaded'); // this is shown on the console. } } 您将收到TypeScript错误,告诉您该窗口没有onYouTubeIframeAPIReady的定义.这很容易通过多种方式解决,但我只是说明两种可能性,要么就是完成工作,技术上也没有必要,因为尽管出现错误,TypeScript仍然会发出代码. >在窗口上指定一个类型断言来抑制错误 (window as any).onYouTubeIframeAPIReady = function () {} >在窗口上声明成员,以便您可以分配给它而不会出现错误.在模块内部(回想一下,我们不在全球范围内),我们可以使用以下形式 declare global { interface Window { onYouTubeIframeAPIReady?: () => void; } } 请记住,所有JavaScript都是有效的TypeScript,并且TypeScript不会向JavaScript添加行为或功能.它是一种类型化的视图,如果您愿意,可以通过JavaScript进行解释,允许对其进行静态验证并具有出色的工具,捕获错误,提供高效的编辑体验,并允许在代码级别记录期望. 这只是JavaScript.它与Youtube iframe api not triggering onYouTubeIframeAPIReady中使用的解决方案完全相同,我只发布它,因为似乎有断开连接. 附录:值得注意的是,如果使用SystemJS或RequireJS等模块加载程序,则可以通过加载程序配置抽象手动脚本标记注入过程.这样做的好处是更清晰,更具说明性的代码以及更高的可测试性,因为您可以存储YouTube依赖关系,将测试与网络隔离开来. 对于SystemJS,您将使用以下配置 SystemJS.config({ map: { "youtube": "https://www.youtube.com/iframe_api" },meta: { "https://www.youtube.com/iframe_api": { "format": "global","scriptLoad": true,"build": false } } }); 你可以写 export default class YouTubeService { async loadAPI() { window.onYouTubeIframeAPIReady = function () { console.log('API loaded'); // this is shown on the console. }; try { await import('youtube'); // automatically injects a script tag } catch (e) { console.error('The YouTube API failed to load'); } } } declare global { interface Window { onYouTubeIframeAPIReady?: () => void; } } 现在,如果您想测试此代码,模拟YouTube API,您可以写 测试/检验存根/存根的YouTube-api.ts (function () { window.onYouTubeIframeAPIReady(); }()); 测试/服务/ YouTube的-service.spec.ts import test from 'blue-tape'; import YouTubeService from 'src/services/youtube.service' SystemJS.config({ map: { "youtube": "test/test-stubs/stub-youtube-api.ts" } }); if(typeof window === 'undefined') { global.window = {}; } test('Service must define a callback for onYouTubeIframeAPIReady',async ({isNot}) => { const service = new YouTubeService(); await service.loadAPI(); t.isNot(undefined,window.onYouTubeIframeAPIReady); }); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |