尝试从 dijit 按钮派生:"类型错误:this._attachEvents未定义"



我试图从dijit/Form/Button中派生一个"扩展"按钮。(我想向构造函数传递额外的参数,并且我想将这些准备工作封装在派生类中。按钮只是一个例子,我想稍后在网格和树中使用它。

不幸的是,下面的代码失败了,出现了"TypeError: this "。_attachEvents在firefox javascript控制台中是未定义的。一些想法,什么是错的?相同的代码,包括最小的HTML,准备在http://jsfiddle.net/x9dLs8gz/1/

上运行
require(["dojo/_base/declare", "dijit/form/Button", "dojo/dom", "dojo/json", "dojo/domReady!"],
function (declare, Button, dom, json) {
    declare("MyButton", Button, {
        "-chains-": {
            constructor: "manual"
        },
        constructor: function () {
            //extra calculation will go here...
            this.inherited(arguments);
        }
    });
    new MyButton({
        label: "Click Me!",
        onClick: function () {
            dom.byId("result").innerHTML += "Success";
        }
    }, "button").startup();
});

欢呼,多米尼克

如果constructor方法的"-chains-"值未设置或设置为"after",则在所有继承的constructor被触发后,将调用postscript方法。另一方面,当指定"manual"时,在执行第一个constructor(在本例中为MyButton#constructor)之后触发postscript。因此,_AttachMixins#buildRendering_AttachMixins#constructor中设置this._attachEvents之前被触发,从而导致您看到的错误。

由于指定"manual"意味着不假设任何链,因此即使this.inherited被正确地向上调用,mixin构造函数也永远不会调用。这是有道理的,因为底层的C3MRO被扔出了窗口。

如果你需要继续使用"manual"设置,尽管如此,你将需要1)自己重新创建任何丢失的数据,2)手动调用mixin构造函数(例如,_AttachMixin.prototype.constructor.call(this)),或3)将MyButton转换为Button的工厂:

var createButton = (function () {
    var myButtonDefaults = { ... };
    return function (kwArgs, id) {
        var buttonId = id || 'button';
        return new Button(lang.mixin({}, myButtonDefaults, kwArgs), buttonId);
    };
})();
var myButton = createButton();
myButton.startup();
console.log(myButton instanceof Button); // true

您需要将声明的类分配给一个变量或在不同的文件中声明并将其添加到require中的对象列表中。也不要使用像"constructor"这样的关键字来命名变量。以下是您的示例的固定版本。

require(["dojo/_base/declare", "dijit/form/Button", "dojo/dom", "dojo/json", "dojo/domReady!"],
  function(declare, Button, dom, json) {
    var MyButton = declare("MyButton", Button, {
      "-chains-": {
        constructorType: "manual"
      },
      constructor: function() {
        //extra calculation will go here...
        this.inherited(arguments);
      }
    });
    new MyButton({
      label: "Click Me!",
      onClick: function() {
        dom.byId("result1").innerHTML += "Success";
      }
    }, "button").startup();
  });
<div id="button"></div>
<div id="result1"></div>

最新更新