我正在尝试用JavaScript创建一些自定义对象,我不确定我是否以正确的方式处理事情。
我有两个对象:' UserInterface'和' VolumeSlider'。直到片刻之前,这两个对象是独立的,但通过方法耦合。我决定UserInterface而不应该“#In;一个VolumeSlider。
所以:
UserInterface = {
_volumeSlider: null,
initialize: function () {
this._volumeSlider = VolumeSlider; //TODO: Should this be a new volumeSlider();
this._volumeSlider.initialize();
//I want to setup a listener for VolumeSlider's change-volume events here.
}
}
VolumeSlider = {
_volumeSlider: null,
initialize: function () {
this._volumeSlider = $('#VolumeSlider');
var self = this;
this._volumeSlider.slider({
orientation: 'horizontal',
max: 100,
min: 0,
value: 0,
slide: function (e, ui) {
self.passVolumeToPlayer(ui.value);
},
change: function (e, ui) {
self.passVolumeToPlayer(ui.value);
}
});
},
passVolumeToPlayer: function (volume) {
if (volume != 0)
UserInterface.updateMuteButton(volume);
else
UserInterface.updateMuteButton('Muted');
}
}
问题是双重的:
答案 0 :(得分:1)
这是创建对象和设置孩子的好方法吗?
如果有效,那就“好吧”:) 但严肃地说,实际上有无数种方法可以设置类似的东西。很大程度上取决于您的需求。
但是,我会说,例如,如果需要超过1个滑块,那么您的代码将变得难以处理。
我希望UserInterface能够响应VolumeSlider._volumeSlider的更改和幻灯片事件,而不必明确告知。我怎样才能完成这个?
我可能只是跳过VolumeSlider
对象。它不是构造函数(“类”),因此它是一次性使用并硬编码到#VolumeSlider
元素。此外,从您的代码中,它并没有真正做。似乎只是一个中间人。
这是另一种选择:
UserInterface = {
initialize: function () {
// Internal function to create a horizontal 0-100 slider
// Takes a selector, and a function that will receive the
// value of the slider
function buildSlider(selector, callback) {
var element = $(selector);
var handler = function (event, ui) { callback(ui.value); };
element.slider({
orientation: 'horizontal',
max: 100,
min: 0,
value: 0,
slide: handler,
change: handler
});
return element;
}
// We probably want to bind the scope of setVolume, so use $.proxy
this.volumeSlider = buildSlider("#VolumeSlider", $.proxy(this.setVolume, this));
// Want more sliders? Just add them
// this.speedSlider = buildSlider("#SpeedSlider", $.proxy(this.setSpeed, this));
// this.balanceSlider = buildSlider("#BalanceSlider", $.proxy(this.setBalance, this));
// etc...
},
setVolume: function (value) {
if( value != 0 ) {
// not muted
} else {
// muted
}
}
}
有了这个,您可以想象为您需要的任何目的创建X个滑块。并且没有单独的一次性VolumeSlider
对象;所有内容都在UserInterface
对象中处理。
当然,这本身可能不是最好的主意,但出于这个简单的目的,它没关系。但是,您可能希望将buildSlider
提取到更通用的UIElements
对象中。它可能包含buildSlider
,buildButton
等方法
或者,您可以使用“Unobtrusive JavaScript”,并拥有特殊的类名和data-
属性,这些属性将声明元素在UI中的位置和位置。例如
<div id="volumeSlider" class="ui-element" data-role="slider" data-action="setVolume">...
可以使用$(".ui-element").each ...
与所有其他UI元素一起找到,之后可以解析其属性以表示它应该被创建为名为“volumeSlider”的滑块,并且其幻灯片/更改事件应该调用{ {1}} ... 等等。
同样,有许多方法可以解决这个问题。
答案 1 :(得分:1)
我认为你的原始结构根本不会变得笨拙。 JavaScript的内置数据结构在这种情况下会有所帮助。
如果您需要多个音量滑块,只需将此位_volumeSlider: null,
更改为_volumeSliders: [],
如果您需要参考滑块,请将_volumeSliders
初始化为dict
。然后通过_volumeSliders[selector]
引用它们,你就得到了你的对象。
不是向上传递值的函数,而是向下发送对父实例的引用。然后你可以写parent.volume = value
。
根据经验,我严格遵循坚实,合乎逻辑的等级结构。永远不要改变您的架构,只需创建范围引用。在这种情况下,对父作用域的引用。我不会使用第一个回答者的方法,因为我可能不得不四处寻找正在创建的对象的来源。
第一个回答者有一些好主意。您可能会注意到某些重复的模式,例如:设置jQuery元素引用。我通常会等到我注意到这些重复的模式,然后DRY以抽象为例,例如像Flambino建议的基类,例如: UIElement
。