我有以下代码
$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函数?
答案 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方式,因为:
答案 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