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

Posted

技术标签:

【中文标题】Dojo:在事件侦听器回调中维护对小部件的引用【英文标题】:Dojo: maintain reference to widget in event listener callback 【发布时间】:2014-10-24 22:38:17 【问题描述】:

我有一个如下所示的 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 获得的。

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

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

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

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

然后从事件对象中获取被点击按钮的id...但这看起来很hacky并且喜欢不正确的处理方式。

这样做的“最佳实践”是什么?

【问题讨论】:

【参考方案1】:

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

来自道场文档:

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

【讨论】:

所以这意味着我应该通过事件对象获取有关事件起源的 DOM 节点的信息? 是使用事件对象,通常使用event.target。您可以在此处找到有关事件对象 API 的更多信息:developer.mozilla.org/en/docs/Web/API/Event

以上是关于Dojo:在事件侦听器回调中维护对小部件的引用的主要内容,如果未能解决你的问题,请参考以下文章

未在 React 中呈现的元素上的触发事件侦听器

如何使用事件侦听器复制DOM节点?

交换 dojox.mobile.Carousel 小部件时处理事件

为啥没有事件侦听器或引用的封闭 NetConnection 会留在内存中?

Android - 查看子项数量更改时的侦听器/回调

每当将 QWidget 添加到 QApplication 的小部件树时,如何接收事件?