【问题标题】:Dojo declare - the scope of default properties (instance or static)Dojo 声明 - 默认属性的范围(实例或静态)
【发布时间】:2013-10-18 10:27:30
【问题描述】:

我花了很多时间调试组件中的策略错误。该组件具有禁用/启用按钮,但我还没有看到效果。过了一会儿,我注意到,按钮在我创建的最后一个组件实例中发生了变化。声明看起来是这样的:

  constructor: function(options) {
    for(var i in options){
      this[i] = options[i];
    }
  },
  domNode: null,
  grid: null,
  data: [],
  buttons: {},

在调试中,我看到,当我创建对象的第二个实例时:

new CustomComponent({domNode: dojo.byId('secondid')})

按钮已设置 - 它们的实例由所有实例共享!

最终,我在组件中创建了一个静态变量。这不是我想要的!该声明有什么问题?我应该如何为每个组件实例分别制作“按钮”实例?

【问题讨论】:

    标签: javascript dojo requirejs declare dojo-1.9


    【解决方案1】:

    我想CustomComponent 是一个小部件?然后你做错了一些事情。您在 constructor 中所做的事情(我想这是为了填充您的小部件属性?)甚至没有必要,因为当您使用 dijit/_WidgetBase 时默认情况下已经存在。

    与您的属性domNode 相同,如果您使用dijit/_WidgetBase,默认情况下它也已经存在。

    我的猜测是,通过重写构造函数来执行这样的操作,您实际上是在执行 WidgetBase 应该执行的一些步骤,从而弄乱了属性的私有范围。

    一个示例小部件:

    var CustomComponent = declare("my/CustomComponent", [WidgetBase], {
        grid: null,
        data: [],
        buttons: {}
    });
    

    此代码与您的小部件完全相同,而且要短得多。

    具有实例范围属性的示例 JSFiddle(如您在控制台日志中所见)。

    【讨论】:

    • 从技术上讲,我的组件是一个小部件,但它不继承任何东西。而且我不认为这是问题所在,似乎 declare 中的所有内容都是一个原型,它被复制到子实例中,所以通过按钮:{} 你创建了一个新对象,它将被复制到所有实例中。所以正确的方法是在构造函数中创建那个对象。
    • 为什么不从 WidgetBase 继承呢?它让事情变得容易多了,而且我看不出有什么缺点。
    • 我不需要来自 WidgetBase 的任何东西,至少我目前不知道任何这样的东西 :)
    【解决方案2】:

    我已经更准确地检查了这个问题。问题是,declare 块只执行一次,因此创建了对象 prototype,其值复制到实例。

    所以当我执行buttons: {} 时,我会创建对象,然后将其复制 给所有孩子。最终,所有孩子都有相同的 buttons 实例 - 我创建了一个准静态字段。

    当我在构造函数中创建对象时,所有错误都消失了:

      constructor: function(options) {
        for(var i in options){
          this[i] = options[i];
        }
        this.buttons = {}
        this.data = []
      },
    

    现在我的组件的每个实例都有自己的buttons 对象。

    其实我的问题也正是here描述的:

    dojo.declare("my.classes.bar", my.classes.foo, {
      someData: [1, 2, 3, 4], // doesn't do what I want: ends up being 
    

    【讨论】:

    • 看起来您自己找到了答案,但here's the documentation 说明了为什么这是必要的。
    • @ThomasUpton 谢谢你的链接,我用它来更新我的答案。好吧,这是 Dojo 的一个问题,您还应该阅读过时的文档 :)
    • 我只是将第一个结果用于 dojo.declare,因为您似乎使用的是 1.6 样式的全局 dojo 对象。 The current documentation 提到了同样的事情。
    猜你喜欢
    • 2017-05-24
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    相关资源
    最近更新 更多