Dojo:在事件侦听器回调中维护对widget的引用

时间:2014-10-24 22:38:18

标签: javascript dojo widget

我有一个Dojo小部件,如下所示:

define([
    // stuff...
], function(declare, lang, win, on, query,
    _WidgetBase, _TemplatedMixin, _OnDijitClickMixin, template){

    return declare("Toolbar", [_WidgetBase, _TemplatedMixin, _OnDijitClickMixin], {
        templateString: template,
        map: null,

        constructor: function(options) {
            // this.map set here
            lang.mixin(this, options);

            if (this.map === null) {
                console.log("Error: no map!");
            }
        },

        postCreate: function() {
            on(this.domNode, ".toolButton:click", this.loadTool);
        },

        // in the following function, this refers to element where event 
        // originated here   
        loadTool: function(e) {
            var clickedTool = "tools/Tool" + this.id[this.id.length - 1];

            require([clickedTool], function(Tool) {
                // Fails: want this.map to refer to map defined by constructor above
                (new Tool({ map: this.map })).placeAt(win.body());
            });
        }
    });
});

目前,这个Toolbar窗口小部件只是一个按钮的有序列表,每个按钮都有一个类toolButton。单击按钮时,它将有条件地加载与单击按钮关联的模块(返回另一个窗口小部件)。为简单起见,工具模块名为tools/Tool<some_number>,其中<some_number>是从点击按钮上的id获得的。

我需要将map小部件的Toolbar属性传递到Tool小部件的构造函数中,如此行所示:

(new Tool({ map: this.map })).placeAt(win.body());

但是,如上所述,在loadTool中,this指的是点击的按钮,而不是Toolbar窗口小部件。一种可能性是将事件监听器称为

on(this.domNode, ".toolButton:clicked", lang.hitch(this, this.loadTool);

然后从事件对象中获取所单击按钮的id ...但这看起来很糟糕,并且像处理错误的方法一样。

什么是最佳实践&#34;这样做?

1 个答案:

答案 0 :(得分:1)

最佳做法是将上下文传递给回调函数,就像第二种方法一样。这允许您控制函数的执行方式,特别是在异步操作中。

来自dojo文档:

on(something, "click", processEvent);
  

在上面的异步回调中,代码所在的上下文   执行中已经改变了。它将不再引用那个对象   最初提供它,但它的上下文现在将引用它   封闭对象,回调。为了解决这个问题,你可以使用   hitch()强制函数保留其原始上下文。

正确完成的相同代码如下所示:

on(something, "click", lang.hitch(this, processEvent));

http://dojotoolkit.org/reference-guide/1.10/dojo/_base/lang.html#dojo-base-lang-hitch