无法覆盖setWidth之类的setter函数

时间:2016-06-15 10:07:53

标签: javascript qooxdoo

我有以下代码

$pipeline = [
    ['$group' => [
        'Players count' => [
            '$sum' => [
                '$cond' => [ [ '$gt' => [ '$stats.games_played',  0 ] ], 1, 0 ] 
            ]
        ],
        'avgGamesPlayed' => [
            '$avg' => '$stats.games_played'
        ],
        'TotalGamesPlayed' => [
            '$sum' => '$stats.games_played'
        ],
    ]],
    ['$sort' => [get('sort', 'count') => (int) get('sort_order', -1)]],
];

$options = [];

$m->aggregate($pipeline, $options);

当从类EditorArea调用setWidth()时,框架总是调用超级函数。

换句话说

qx.Class.define("myproject.EditorArea",
{
  extend : qx.ui.container.Composite,

  events : {
  },

   statics :
   {
   },

  members :
  {
    __htmlArea : null,
    __txtArea : null,

    setWidth : function( value )
    {
      this.__htmlArea.setWidth( value );
      this.__txtArea.setWidth( value );
      return( value );
    },
    setHeight : function( value )
    {
      this.__htmlArea.setHeight( value -19 );
      this.__txtArea.setHeight( value -19 );
      return( value );
    }

},

   /**
    * Constructor
   * @param sHtml {String} the initial html value for this widget.
    */
   construct : function( sHtml )
  {
   this.base(arguments);

    this.setLayout( new qx.ui.layout.VBox(1));

    var container = new qx.ui.container.Composite(new qx.ui.layout.HBox( 1, "right" )).set( {height:18} );
    this.__htmlArea = new qx.ui.embed.Html( sHtml );
    this.add(this.__htmlArea);
    this.__txtArea = new qx.ui.form.TextArea("");
  }
});

调用qx.ui.container.Composite.setWidth()而不是 myproject.EditorArea.setWidth()。

永远不会达到被覆盖的功能。如何覆盖那些setter函数?

5 个答案:

答案 0 :(得分:4)

getter和setter函数是在qx.Class.define()期间以编程方式生成的。通常,您不想尝试弄乱它们。如果你想要自己的,你最好创建setMyWidth()和setMyHeight()函数,即一些非自动生成名称的函数。

如果您确实希望函数名称为setWidth / setHeight,则可以尝试在类定义的 defer 部分中创建这些函数。传递给qx.Class.define的map的defer元素与构造,事件,静态,成员(参见文档)处于同一级别,并且在完全定义类之后运行其函数中的代码。您可以通过在那里添加自定义函数来覆盖/完全覆盖自动生成的getter和setter。但是,你在这里处于未知领域,我不建议。

Derrell

答案 1 :(得分:3)

正如Derrell已经说过的那样,可以通过技巧覆盖qooxdoo属性的自动生成的setter和getter,但不推荐。

但是,通过覆盖_applyDimension中定义的宽度和高度的属性应用程序qx.ui.core.LayoutItem,可能会有一个解决方案。

每次更改房产时都会调用应用程序。请阅读http://demo.qooxdoo.org/current/apiviewer/#qx.core.Property

上的对应文档

您的覆盖如下:

_applyDimension : function(newValue, oldValue, propertyName) {
  if(propertyName == "width") {
    this.__htmlArea.setWidth( newValue );
    this.__txtArea.setWidth( newValue );
  }
  if(propertyName == "height") {
    this.__htmlArea.setWidth( newValue-19 );
    this.__txtArea.setWidth( newValue-19 );
  }

  this.base(arguments, newValue, oldValue, propertyName);
}

必须通过调用this.base(arguments,...)来调用超类方法,以便不破坏继承路径上的上游功能,或者当然,您希望明确地这样做。

这种方式是安全的并且有记录。

答案 2 :(得分:3)

未调用setHeight和setWidth的原因是因为您在示例中从不调用它们;请看一下这个版本的示例,你可以看到派生类中的setWidth / setHeight 被称为,如果你调用它们(你需要点击“Log”按钮查看证明这一点的调试输出

qx.Class.define("myproject.EditorArea", {
  extend: qx.ui.container.Composite,

  members: {
    __htmlArea: null,
    __txtArea: null,

    setWidth: function(value) {
      this.debug("in setWidth");
      this.__htmlArea.setWidth(value);
      this.__txtArea.setWidth(value);
      return (value);
    },
    setHeight: function(value) {
      this.debug("in setHeight");
      this.__htmlArea.setHeight(value - 19);
      this.__txtArea.setHeight(value - 19);
      return (value);
    }

  },

  construct: function(sHtml) {
    this.base(arguments);

    this.setLayout(new qx.ui.layout.VBox(1));
    this.__htmlArea = new qx.ui.embed.Html(sHtml);
    this.add(this.__htmlArea);
    this.__txtArea = new qx.ui.form.TextArea("");
  }
});

var test = new myproject.EditorArea();
test.set({ width: 200, height: 300 }); // outputs "in setWidth" and "in setHeight" 
test.set({ width: 250, height: 350 }); // outputs "in setWidth" and "in setHeight"

(但请注意,虽然这在操场上有效,但调试编译器会阻止您覆盖属性访问者 - 我已经在这里讨论过这个问题https://github.com/qooxdoo/qooxdoo/issues/9053

你想要实现的大局是将小部件嵌入到另一个小部件中并控制布局 - 但是你所采用的方法不起作用,因为你没有调用超类setWidth和setHeight,这意味着你将防止小部件除了零宽度和高度之外还有其他任何东西。无论您的htmlarea和文本区域有多大,它们都将永远不可见,因为它们的容器宽度/高度为零。

更改布局工作方式的正确方法是选择不同的布局(即qx.ui.layout。*类)或者可能编写自己的布局,尽管考虑到现有布局类的灵活性,很少需要IMHO

:: EDIT :: 虽然我在上面指出调试编译器不允许覆盖属性访问器,但截至2016年6月22日已发生变化.Qooxdoo已升级为支持覆盖属性访问器超类中定义的方法;这是在主分支中,并将成为Qooxdoo 6.0稳定版本的一部分

答案 3 :(得分:2)

这不是qooxdoo方式,因为:

  1. 要解决此任务,通常使用绑定+侦听器+布局管理器。
  2. 在这种情况下,属性设置器工作得很快,因为布局管理器会在其队列中安排更新,但如果它运行缓慢怎么办?该属性设计为快速,让开发人员易于阅读。 Setter / getter call不能花费太多时间。

答案 4 :(得分:1)

另外,只是为了增加讨论,当我们设置属性时,有时我们不只是想同时做其他事情,就像这个问题的情况一样。我们可能还希望在设置它之前对其进行转换,验证它或者只是检查它是否采用正确的格式。与_apply qooxdo一起提供了属性定义中的其他键。例如

properties : {
  myProp : {
        apply : "_applyMyProp",
        transform: "_transformMyProp",
        check: "_checkMyProp",  
        validate: "_validateMyProp"}
},

members :
{
  _applyMyProp : function(value, old, name) {
    // do something with the value 
  },

  _transformMyProp: function(value){
    // transform the value before being checked and validated and set
  },

  _checkMyProp: function(value){
    // check the value when on debug mode
  },

  _validateMyProp: function(value){
   // validate the value before set even when not in debug mode
  },
}

以下是更多详情http://manual.qooxdoo.org/5.0.1/pages/core/defining_properties.html