应该在dojo子类

时间:2015-09-23 16:31:31

标签: javascript events inheritance dojo

我正在使用dojo在javascript中设计一个抽象超类。该类的目的是为任何UI元素定义合同,使用户能够选择具有唯一标识符的实体。到目前为止,这是我的代码。

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;
        }

    });
});

我还需要子类触发onSelect事件,因此我可以响应实际选择实体的用户。

是否有方法(文档除外)表明子类应在其实现上触发onSelect事件?

例如,在Java中,您通常会定义一个public void addEventListener(ListenerInterface)方法来指示子类应该触发事件。在C#中,您可以声明event EventHandler来实现类似的功能。

在dojo或一般Javascript中有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:0)

您可以使用类似下面的代码。
它依赖于_WidgetBase提供的小部件生命周期,并检查是否实现了某些方法 此外,当“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>