如何使用复选框创建自定义列表项?

How to create customized list item with checkbox?

我创建了一个 qooxdoo 列表,其中包含包含复选框和标签的自定义项。 我的问题是:当我选中该复选框时,它会变大,这会带来难看的用户体验。此外,当我检查一些第一个项目并向下滚动时,我看到许多项目被选中,默认情况下应该取消选中。

这是有人可以粘贴到 play ground for qooxdoo 中的代码:

// Create a button
var button1 = new qx.ui.form.Button("click to see list!", "icon/22/apps/internet-web-browser.png");

// Document is the application root
var doc = this.getRoot();

// Add button to document at fixed coordinates
doc.add(button1,
{
  left : 100,
  top  : 50
});

var popup;
// Add an event listener
button1.addListener("execute", function(e) {
  if (!popup) {
    popup = new myApp.list();
  }
  
  popup.placeToWidget(button1);
  popup.show();
});

/*
 * class: list inside popup.
*/
qx.Class.define("myApp.list", 
{
 extend : qx.ui.popup.Popup,
 
 construct : function() 
 {
  this.base(arguments);
  this.__createContent();
 },
 
 members : {
  __createContent : function(){
   this.set({
    layout : new qx.ui.layout.VBox(),
    minWidth : 300
   });

   
   //prepare data
      var zones = [];
      for (var i=0; i<100; i++){
        zones.push({"LZN" : "ZONE " + i, "isChecked" : false});
      }
      
      var lstFences = new qx.ui.list.List();
   this.add(lstFences, {flex : 2});
   
   var delegate = {
           createItem : function() {
             return new myApp.customListItem();
           },

           bindItem : function(controller, item, id) {
             controller.bindProperty("isChecked", "isChecked", null, item, id);
             controller.bindPropertyReverse("isChecked", "isChecked", null, item, id);            
             controller.bindProperty("LZN", "LZN", null, item, id);                        
           }
      };
        
      lstFences.setDelegate(delegate);
   lstFences.setModel(qx.data.marshal.Json.createModel(zones));
   lstFences.setItemHeight(50);
  }
 }
})


/**
 * The custom list item
 */

qx.Class.define("myApp.customListItem",  {
 extend : qx.ui.core.Widget, 
  
 properties :
 {
  LZN:
  {
    apply  : "__applyLZN",
    nullable  : true
  },
 
  isChecked :
  {
    apply  : "__applyChecked",
    event  : "changeIsChecked",
    nullable  : true
  }
 },
 
 construct : function()
 {
  this.base(arguments);
   this.set({
     padding  : 5,
     decorator : new qx.ui.decoration.Decorator().set({
         bottom    : [1, "dashed","#BBBBBB"]
        })
  });
  
  this._setLayout(new qx.ui.layout.HBox().set({alignY : "middle"}));
 
  // create the widgets
  this._createChildControl(("isChecked"));
  this._createChildControl(("LZN"));
 },
 
 members :
 {
  // overridden
  _createChildControlImpl : function(id)
  {
    var control;
 
   switch(id)
   {
       case "isChecked":
        control = new qx.ui.form.CheckBox();
        control.set({
         padding : 5,
         margin : 8,
         value : false,
         decorator : new qx.ui.decoration.Decorator().set({
             width : 2,
             color : "orange",
             radius : 5
            })
       });
        this._add(control);
        break;
    
    case "LZN":
     control = new qx.ui.basic.Label();
     control.set({allowGrowX : true});
     this._add(control, {flex : 2});
        break; 
     }
   
     return control || this.base(arguments, id);
  },
 
  __applyLZN : function(value, old) {
   var label = this.getChildControl("LZN");
   label.setValue(value);
  },
  
  __applyChecked : function(value, old)
  {
   var checkBox = this.getChildControl("isChecked");
   console.log(value, old);
   checkBox.setValue(value);
  }
 }
});

这里有两个问题:

第一个事实是,通过 _createChildControlImpl 将复选框创建为子窗口小部件会使复选框失去其外观(在 qooxdoo 主题外观的意义上),从而导致丢失 minWidth 属性使复选框在未选中时宽度为 0,在选中时显示复选标记所需的宽度。这里的解决方案是像这样向 myApp.customListItem class 添加外观:

properties : { appearance: { refine : true, init : "mycustomlistitem" } } 然后为您的主题添加相应的外观: appearances : { "mycustomlistitem" : "widget", "mycustomlistitem/isChecked" : "checkbox" } 您还可以添加在外观定义中实例化复选框(橙色装饰器等)时完成的所有样式。

第二个问题是您只定义了自定义列表项的复选框子小部件与其 "isChecked" 子小部件之间的单向绑定。此处需要双向绑定,因此如果 属性 "isChanged" 的值发生变化,它会将其传递给复选框,反之亦然。

我已经相应地修改了你的 playground 示例,方法是动态创建缺失的外观并在复选框和列表项“isChecked”之间创建双向绑定 属性。请注意,为了简单起见,我直接在应用程序根目录中创建了列表:

https://gist.github.com/level420/4662ae2bc72318b91227ab68e0421f41