指示应在 dojo 子类中触发事件的最佳方式
Best way to indicate an event should be fired in a dojo subclass
我正在使用 dojo 在 javascript 中设计一个抽象的 superclass。 class 的目的是为任何 UI 元素定义契约,使用户能够 select 具有唯一标识符的实体。到目前为止,这是我的代码。
define(
[
"dojo/Evented",
"dojo/_base/declare"
],
function(Evented, declare){
var NotImplementedException = "Method not implemented";
return declare("EntitySelector", Evented, {
//it's implementation should change the entity selected by the UI
select: function(id){
throw NotImplementedException;
},
//it's implemantation should populate the UI with the data to be selected.
setData: function(dataStore){
throw NotImplementedException;
}
});
});
我还需要 subclasses 触发一个 onSelect 事件,这样我就可以响应用户实际 selecting 一个实体。
有没有办法(文档除外)指示子classes 应该在其实现时触发 onSelect 事件?
例如,在 Java 中,您通常会定义一个 public void addEventListener(ListenerInterface)
方法来指示子classes 应该触发一个事件。在 C# 中,您可以声明一个 event EventHandler
来实现类似的效果。
在 dojo 或通用 Java 脚本中有没有办法实现这个?
您可以使用类似下面的代码。
它依赖于 _WidgetBase 提供的 widget 生命周期,并检查是否实现了某些方法。
此外,它会在触发 "select" 方法时自动添加 "onSelect" 事件。
另一种方法是挂钩 on
方法并检查是否附加了事件(查看 foo
事件的情况。
require([
"dojo/Evented",
"dojo/aspect",
"dijit/_WidgetBase",
"dojo/_base/lang",
"dojo/_base/declare"
], function(Evented, aspect, _WidgetBase, lang, declare) {
var NotImplementedException = "Method not implemented";
var EntitySelector = declare([_WidgetBase, Evented], {
hasOnFooEvent: false,
postMixInProperties: function() {
if (typeof this.select !== 'function') {
throw NotImplementedException;
} else {
this.own(aspect.after(this, 'select', lang.hitch(this, 'emit', 'onSelect')))
}
if (typeof this.setData !== 'function') {
throw NotImplementedException;
}
this.inherited(arguments);
},
on: function(eventName) {
if(eventName === 'foo') {
this.hasOnFooEvent = true;
}
this.inherited(arguments);
},
postCreate: function() {
if(!this.hasOnFooEvent) {
throw NotImplementedException;
}
this.inherited(arguments);
}
});
var NotOkWidget = declare(EntitySelector, {});
var OkWidget = declare(EntitySelector, {
postCreate: function() {
this.on('foo', function() {});
this.inherited(arguments);
},
select: function() {},
setData: function() {}
});
try {
var a = new NotOkWidget();
} catch (e) {
console.log('Implementation error on NotOkWidget');
}
try {
var a = new OkWidget();
a.on('onSelect', function() { console.log('onSelect event is fired'); });
a.select();
} catch (e) {
console.log('Implementation error on OkWidget');
}
});
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
我正在使用 dojo 在 javascript 中设计一个抽象的 superclass。 class 的目的是为任何 UI 元素定义契约,使用户能够 select 具有唯一标识符的实体。到目前为止,这是我的代码。
define(
[
"dojo/Evented",
"dojo/_base/declare"
],
function(Evented, declare){
var NotImplementedException = "Method not implemented";
return declare("EntitySelector", Evented, {
//it's implementation should change the entity selected by the UI
select: function(id){
throw NotImplementedException;
},
//it's implemantation should populate the UI with the data to be selected.
setData: function(dataStore){
throw NotImplementedException;
}
});
});
我还需要 subclasses 触发一个 onSelect 事件,这样我就可以响应用户实际 selecting 一个实体。
有没有办法(文档除外)指示子classes 应该在其实现时触发 onSelect 事件?
例如,在 Java 中,您通常会定义一个 public void addEventListener(ListenerInterface)
方法来指示子classes 应该触发一个事件。在 C# 中,您可以声明一个 event EventHandler
来实现类似的效果。
在 dojo 或通用 Java 脚本中有没有办法实现这个?
您可以使用类似下面的代码。
它依赖于 _WidgetBase 提供的 widget 生命周期,并检查是否实现了某些方法。
此外,它会在触发 "select" 方法时自动添加 "onSelect" 事件。
另一种方法是挂钩 on
方法并检查是否附加了事件(查看 foo
事件的情况。
require([
"dojo/Evented",
"dojo/aspect",
"dijit/_WidgetBase",
"dojo/_base/lang",
"dojo/_base/declare"
], function(Evented, aspect, _WidgetBase, lang, declare) {
var NotImplementedException = "Method not implemented";
var EntitySelector = declare([_WidgetBase, Evented], {
hasOnFooEvent: false,
postMixInProperties: function() {
if (typeof this.select !== 'function') {
throw NotImplementedException;
} else {
this.own(aspect.after(this, 'select', lang.hitch(this, 'emit', 'onSelect')))
}
if (typeof this.setData !== 'function') {
throw NotImplementedException;
}
this.inherited(arguments);
},
on: function(eventName) {
if(eventName === 'foo') {
this.hasOnFooEvent = true;
}
this.inherited(arguments);
},
postCreate: function() {
if(!this.hasOnFooEvent) {
throw NotImplementedException;
}
this.inherited(arguments);
}
});
var NotOkWidget = declare(EntitySelector, {});
var OkWidget = declare(EntitySelector, {
postCreate: function() {
this.on('foo', function() {});
this.inherited(arguments);
},
select: function() {},
setData: function() {}
});
try {
var a = new NotOkWidget();
} catch (e) {
console.log('Implementation error on NotOkWidget');
}
try {
var a = new OkWidget();
a.on('onSelect', function() { console.log('onSelect event is fired'); });
a.select();
} catch (e) {
console.log('Implementation error on OkWidget');
}
});
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>