gpt4 book ai didi

javascript - "inner"要求的 Dojo 范围问题

转载 作者:行者123 更新时间:2023-11-30 18:25:06 25 4
gpt4 key购买 nike

我确定“内在要求”不是正确的术语,但它很快就会在这里有意义。我正在研究工具包网站上的 Dijit 教程,我遇到了一个问题,我认为这个问题更像是对 Javascript 的理解,而不是对 Dojo 的理解。

我的页面初始化脚本:

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”构造函数

constructor : function(opts){
(function($){
require(['sg/player/component/Video', 'sg/player/component/Audio'], function(Video, Audio){
$._setMedia( (opts.type == 'video') ? new Video() : new Audio());
console.log($._media) // outputs an object "a"
})
})(this);
console.log(this._media) // also outputs the correct object, "a"
}

// the internal setter function used above
_setMedia : function(m){
this._media = m;
},

(我有一个匿名函数的原因是我不喜欢在 require block 中分配 var self = thisthis 不是包含对象。)

当我在初始化脚本中创建 new Player() 对象时,我可以看到 AudioVideo 的新实例被正确分配。但是,当我在初始化脚本中调用 p.setSource() 时,我得到一个错误,指出 _media 为空!

步骤

  • 创建播放器
    • 解析配置选项(类型、维度等)。内部 _media 对象包含 VideoAudio
    • 的实例
  • 允许在 Player 源代码之外访问 setter 方法 !!错误!!

所以我的问题是,希望我提供了足够的上下文,但是为什么 _media 变量失去了它的值(value)?从 Dijit 源代码外部访问的 Player 实例中的任何方法都不应该对内部变量的范围产生任何影响,但这似乎正在发生。构造函数返回后,应该设置_media!但是使用

setSource : function(s){
console.log('Setting source: ', s, this._media)
// outputs ("Setting source: path/to/video.webm', null)
},

...抛出错误,因为它在 setSource 中引用的 _media 变量应该为空。

希望这很清楚:)

更新

希望我能给你们两个打勾!感谢您抽出时间提供帮助。

@Frode:肯定有一些异步问题迫使我学习并尝试更多结构,所有这些都失败了,导致了这次更新。我认为在某些时候文件被缓存,导致变量内容不一致。

@phusick:我混合了你在下面发布的建议。

我考虑重做如何实例化 Player 的结构、对象 arg 等,但决定执行以下操作,以防万一有人遇到此问题...

我将 AudioVideo 类合并到 _Media 文件中,使用此结构(为简洁起见删除了代码)

define(['dojo/_base/declare'], function(declare){
var _base = declare("_Media", null, {
constructor : function(type){
this._type = type;
},
// etc
})
return {
Video : function(){
return declare("Video", _base, {
constructor : function(){
this.inherited(arguments, ['video'])
}
// etc
})()
},
Audio : function(){
return declare("Audio", _base, {
constructor : function(){
this.inherited(arguments, ['audio'])
}
// etc
})()
},
}
})

...这样一开始只有一个文件被加载,它包含两个子类。 IMO,总比加载 2 个单独的文件而不使用一个文件要好。

对于播放器类型实例,它变成了:

this._media = opts.type && opts.type == 'video' ? new Media.Video() : new Media.Audio();

到目前为止一切顺利!再次感谢。

最佳答案

After the constructor returns, _media should be set!

我认为这是你走错了一步的地方。请记住 require 是一个异步函数!

但是,我对构造函数中的这一行(特别是注释)感到有些困惑:

console.log(this._media) // also outputs the correct object, "a"

您能 100% 确定这会输出“a”而不是 null 吗?如果你是,请忽略我的其余答案,因为那样我误解了一些东西:)

好的,如果您还在阅读,我将尝试解释异步要求。当你打电话时:

require([".../Video",".../Audio"], function(Video, Audio) {
// do something and set _media
});

你基本上是在说:“浏览器,你去后台为我获取视频和音频模块,而我继续我的下一行代码。当你获取它们时,运行我给你的那个函数集_媒体。”

换句话说,在 require() 完成并设置 _media 之前可能需要很长时间,但您的代码会立即继续。所以当你调用 setSource 时,require() 可能还没有完成(事实上,它甚至可能还没有开始下载任何东西)。

希望对您有所帮助!

关于javascript - "inner"要求的 Dojo 范围问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11088881/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com