Javascript Dojo范围问题,带有;“内部”;要求
我确信“内在需求”不是正确的术语,但它很快就会有意义。我正在工具包的网站上编写Dijit教程,我遇到了一个问题,我认为这更像是一个Javascript理解问题,而不是Dojo理解问题 我的页面初始化脚本:Javascript Dojo范围问题,带有;“内部”;要求,javascript,dojo,Javascript,Dojo,我确信“内在需求”不是正确的术语,但它很快就会有意义。我正在工具包的网站上编写Dijit教程,我遇到了一个问题,我认为这更像是一个Javascript理解问题,而不是Dojo理解问题 我的页面初始化脚本: require(['player', 'dojo/dom', 'ready'], function(Player, dom){ var p = new Player({ type : 'video', dimensions : [720, 480]
require(['player', 'dojo/dom', 'ready'], function(Player, dom){
var p = new Player({
type : 'video',
dimensions : [720, 480]
});
p.setSource('videos/myvideo.webm')
p.placeAt(dom.byId('stage') )
})
还有我的dijit“player.js”构造函数
(我在那里使用匿名函数的原因是我不喜欢将var self=this
赋值为require
块中的this
不是包含的对象。)
当我在init脚本中创建new Player()
对象时,我可以看到Audio
或Video
的新实例被正确分配。但是,当我在init脚本中调用p.setSource()
时,我得到一个错误,即\u media
为空
步骤
- 创建玩家
- 解析配置选项(类型、维度等)。内部
对象保存\u media
或视频
音频
- 解析配置选项(类型、维度等)。内部
- 允许setter方法在
播放器之外访问
源!!错误强>
\u media
变量失去了它的值呢?从Dijit源代码之外访问Player
实例中的任何方法都不应该对内部变量的范围产生任何影响,但这似乎是正在发生的事情。构造函数返回后,应设置\u media
!但是使用
setSource : function(s){
console.log('Setting source: ', s, this._media)
// outputs ("Setting source: path/to/video.webm', null)
},
…引发错误,因为它在setSource
中引用的\u媒体
变量假定为空
希望这是清楚的:)
更新
但愿我能给你们两个打勾!谢谢你抽出时间帮忙
@弗罗德:肯定有一些异步问题迫使我学习和尝试更多的结构,所有这些都失败了,导致这次更新。我认为在某些情况下,文件被缓存,导致变量内容不一致
@普西克:我混合了你的建议,贴在下面
我曾考虑过重做播放器的实例化结构、对象arg等,但决定做以下操作,以防有人碰到这个问题
我使用此结构将音频
和视频
类合并到\u媒体
文件中(为简洁起见删除了代码)
…这样一来,最初只加载一个文件,并且它包含两个子类。IMO说,这比在一个文件不使用时加载两个单独的文件要好
对于玩家类型实例,它变成:
this._media = opts.type && opts.type == 'video' ? new Media.Video() : new Media.Audio();
到目前为止还不错!再次感谢
构造函数返回后,应设置\u介质
我认为这是你迈出错误的一步。请记住,require是一个异步函数
但是,我对构造函数中的这一行(特别是注释)有点困惑:
您是否100%确定输出“a”而不是空值?如果你是,请忽略我其余的回答,因为这样我就误解了:)
好的,如果你还在读,我会试着解释一下。当你打电话时:
require([".../Video",".../Audio"], function(Video, Audio) {
// do something and set _media
});
你基本上是说:“浏览器,你去后台为我取视频和音频模块,我继续我的下一行代码。当你取完它们后,运行我给你的功能,设置媒体。”
换句话说,require()完成并设置\u media
可能需要很长时间,但您的代码会立即继续。因此,当您调用setSource时,require()可能还没有完成(实际上,它甚至可能还没有开始下载任何东西)
希望有帮助 @Frode是对的。事实上,即使异步操作足够快,它也不会工作,因为JavaScript是单线程的,异步回调进入事件队列并通过一个接一个地执行 请参阅我对这一问题的答复 你的player.js不是这样的原因是什么:
define([
"sg/player/component/Video",
"sg/player/component/Audio"
], function(
Video,
Audio
) {
return declare([SomeSuperClass], {
constructor: function(opts) {
var media = opts.type && opts.type == "video" ? new Video() : new Audio();
this._setMedia(media);
}
});
});
我明白了。。。感谢您提醒我们
require
的异步性质。我看了更多的文档,根据你的回答,我学到了一两件事。稍后我会继续研究,并提供更新。有趣的是,在你回应之前不久,你在屋外研究时提到了我看到的链接。我不立即加载视频和音频的原因是它们可能不需要。我需要一个同步的条件require块,我会看看延迟,但我可能只是将音频和视频合并到一个媒体类/文件中。谢谢
console.log(this._media) // also outputs the correct object, "a"
require([".../Video",".../Audio"], function(Video, Audio) {
// do something and set _media
});
define([
"sg/player/component/Video",
"sg/player/component/Audio"
], function(
Video,
Audio
) {
return declare([SomeSuperClass], {
constructor: function(opts) {
var media = opts.type && opts.type == "video" ? new Video() : new Audio();
this._setMedia(media);
}
});
});