0

我想在 Java 类中使用数据绑定而不是

@绑定

使用Listbox中的每个ListCell。我试过这个例子

我的 ZUL 文件...

<zk>
  <window border="normal" title="hello" apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('com.test.binding.TestRenderer')" >
     <button label="ClickMe" id="retrieve"
                        onClick="@command('onOK')">
                    </button>
    <div height="800px">
      <listbox model="@load(vm.model)" itemRenderer="@load(vm.itemRenderer)" vflex="true" multiple="true"/>
    </div>
  </window>
</zk>

我的 Java 类或 ViewController .....

package com.test.binding;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.zk.ui.Component;
import org.zkoss.zkplus.databind.AnnotateDataBinder;
import org.zkoss.zkplus.databind.Binding;
import org.zkoss.zkplus.databind.BindingListModelList;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Textbox;


public class TestRenderer {

    ListModelList model = new ListModelList();
    private AnnotateDataBinder binder;

    @AfterCompose
    public void afterCompose(@ContextParam(ContextType.VIEW) Component view) {
        binder = new AnnotateDataBinder(view);
     List persons = new ArrayList();    
     model.add(new Person("David", "Coverdale"));
     model.add(new Person("Doug", "Aldrich"));
     model.add(new Person("Reb", "Beach"));
     model.add(new Person("Michael", "Devin"));
     model.add(new Person("Brian", "Tichy"));


        binder.loadAll(); 


    }

    public void setModel(ListModelList model) {
        this.model = model;
    }

    public ListModel getModel() {

        return model;
    }

    // method for ZK 6
    public ListitemRenderer getItemRenderer() {
        ListitemRenderer _rowRenderer = null;
        if (_rowRenderer == null) {

            _rowRenderer = new ListitemRenderer() {
                public void render(final Listitem item,   Object object,
                        int index) throws Exception {
                    final Person dataBean = (Person) object;

                    binder.bindBean(item.getId() , dataBean);

                    Listcell cell = new Listcell();
                    Textbox name = new Textbox();
                    name.setValue(dataBean.getFirstName());
                    System.out.println(item.getId()+ "------------------>"+item.getId() + ".name");
                    //binder.addBinding(name, "value", item.getId()+i + ".name", null, null, "both", null, null, null, null);
                    //binder.addBinding(name, "value",item.getId() + ".name", new String[] {}, "none", "both", null);
                    cell.appendChild(name);
                    //cell.addAnnotation(cell, "bind", null);
                    cell.setParent(item);

                }
            };
            binder.saveAll();
            binder.loadAll();
        }
        return _rowRenderer;
    }
    @Command
    public void onOK() {
        binder.saveAll(); //load Inputfields from Form, Constraints will be performed

        binder.loadAll(); 
       Collection<Binding> test =  binder.getAllBindings();
        System.out.println(model);
      }
    public class Person {
        private String firstName;
        private String lastName;

        public Person(String fn, String ln) {
            setFirstName(fn);
            setLastName(ln);
        }

        public String getFirstName() {
            return firstName;
        }
        public void setFirstName(String fn) {
            firstName = fn;
        }

        public String getLastName() {
            return lastName;
        }
        public void setLastName(String ln) {
            lastName = ln;
        }

    }

    @Command
     public void clickMe(){
        BindingListModelList blml =  (BindingListModelList) getModel();

        for (Object object : blml) {
          System.out.println(Integer.parseInt((String) object));
        }
    }
}

任何人都可以给我演示示例绑定应该如何使用

getItemRendered()

列表框中

谢谢

4

3 回答 3

3

您正在尝试混合不同的范例。您想使用数据绑定,尤其是 MVVM 样式,但还要在此过程中引入您的自定义渲染器。即使这有效,我认为这是一个非常糟糕的做法。要么使用纯 MVVM 数据绑定,将视图与模型分开,只在视图中定义绑定,要么使用纯 MVC 并使用你自己的渲染器来渲染你想要的模型数据。

数据绑定的全部意义在于让 binder 根据数据绑定注释来处理渲染/更新组件状态。

在这里专门讨论您正在使用的示例代码org.zkoss.bind.BindComposer,它将自动初始化一个活页夹实例,然后您还显式地实例化一个单独AnnotateDataBinder的 in,@AfterCompose因此这两者之间会有冲突。

我的建议是通过在您的视图中引入纯 MVVM 数据绑定,<template>并让 MVVM 绑定器使用@Bind@Load注释呈现此模板,或者使用纯 Java 样式的 MVVM 数据绑定,如“ Java 中的 MVVM ”文章中所述

于 2012-12-12T03:59:35.773 回答
0

在我看来,将 ListitemRenderer 与 MVVM 一起使用并没有那么糟糕,有时它可以成为 zul 页面和 ViewModel 之间的“桥梁”,并且可以将其视为组件的一部分(因为一旦分配了模型,列表框将使用默认渲染器如果您不分配模板或自定义渲染器,则渲染项目)(请参阅列表模型)。如果默认渲染器只分配模型和渲染项目没有什么不好,那么将模型和自定义渲染器都分配给渲染项目也没什么不好。

让我们首先定义什么是“好”: -- zul 文件不需要知道 ViewModel 是如何工作的,只需根据需要询问数据和触发命令。-- ViewModel 不需要知道 zul 页面中的任何内容,只需提供数据并处理一些预定义的事件。

现在考虑一个简单的场景,就像官方文档中描述的那样: Performing Actions on Events

看到这条线

onClick="@command('deleteOrder', cartItem=cartItem)"

这条线

public void deleteOrder(@BindingParam("cartItem") CartItem cartItem)

在这种情况下,zul 页面需要知道在事件触发时将参数带到 deleteOrder 命令,甚至必须知道参数应该在 ViewModel 中分配名为 cartItem 的变量。另一方面,ViewModel 需要检索从 zul 页面传递的参数。

这显然不是“好”的情况。

使用 ListitemRenderer,比方说 ShoppingcartOrderlistItemRenderer,我们可以简单地将带有所需数据的事件发布到 Listbox(例如 onDeleteOrder),然后使其变为

<listbox onDeleteOrder="@command('deleteOrder')" ...

public void deleteOrder(@ContextParam(ContextType.TRIGGER_EVENT) DeleteOrderEvent event) {
    getShoppingCart().remove(event.getProductId());
}

依赖事件而不是依赖 zul 页面中定义的参数,我认为这更健壮。

最后,还是不得不说,只是个人意见。

于 2012-12-15T17:10:37.727 回答
0

@subodh

您也可以尝试在 ListitemRenderer 中添加 EventListener 并将一些带有所需数据的自定义事件传递给列表框,然后将该自定义事件绑定到 ViewModel,请参考 github 上的示例项目在线演示

编辑:

我的博客上的相关帖子:ZK Listbox: Event Processing with Renderer and MVVM

于 2012-12-16T06:42:56.243 回答