资料驱动的元件

资料驱动绘制 (Model-driven Rendering)

英雄列表范例已经初步展示过 Listbox 的用法,你应该可以观察到它的架构也可分成 MVC三个角色,Listbox 会根据你所指定的资料物件来绘制子元件 Listitem,当你呼叫 ListModel的 method 来变更资料量的时候(如 add(), remove(), clearAll()),ListModel 内部会通知 Listbox 并更新画面。

静态与动态产生的差别

ZK 支援直接在 zul 中定义元件与子元件,这是「静态产生」元件,例如:

<listbox id="box">
		<listhead sizable="true">
			<listheader label="name" sort="auto" />
			<listheader label="gender" sort="auto" />
		</listhead>
		<listitem>
			<listcell label="Mary" />
			<listcell label="FEMALE" />
		</listitem>
		<listitem>
			<listcell label="John" />
			<listcell label="MALE" />
		</listitem>
		<listitem>
			<listcell label="Jane" />
			<listcell label="FEMALE" />
		</listitem>
		<listitem>
			<listcell label="Henry" />
			<listcell label="MALE" />
		</listitem>
</listbox>

而「动态产生」元件就是要创造一个 ListModelList 给元件,虽然两种方法产生的元件功能相同,不过内部运作稍有不同。主要的差别在於:「状态储存的位置不同:资料驱动绘制的元件,状态储存与控制都在资料模型 (ListModel),而静态产生的状态是存在元件中」

以 Listbox 为例,资料驱动绘制的状况下,要取得被选择的项目是要从 ListModelList 中取得:

model.getSelection(); //回传资料物件如 Hero

Listbox.getSelectedItem() 回传的是被选择的 Listitem,而不是资料。

用 Java 选择项目也一样:

model.addToSelection(hero); //传入资料物件而不是 Listitem

如果要启用多选模式,也是呼叫 ListModelList.setMultiple(true) 而不是元件上 Listbox.setMultiple()

String[] names = {"Mary", "John", "Jane", "Henry"};
ListModelList model = new ListModelList(names);
model.setMultiple(true);

在 ZK 的元件中,许多元件都支援这样的特性,不过他们可以支援的 model 类别不同。

支援 ListModel

  • Chosenbox
  • Combobox
  • Grid
  • Listbox
  • Searchbox
  • Selectbox
  • Tabbox

支援 TreeModel

  • Tree
  • Organigram

绘制器

先前英雄列表范例中提到用 <template> 定义绘制的范本,但如果你要在执行期根据各种情况来绘制时怎麽办呢?对应 <template>的 Java 作法就是实作绘制器介面,不同的元件需要实作不同的介面,如 Listbox 需要实作 ListitemRenderer,范例如下:

public class MyRenderer implements ListitemRenderer{
		public void render(Listitem listitem, Object data, int index) {
				Listcell cell =new Listcell();
				listitem.appendChild(cell);
				if (datainstanceof String[]){
					cell.appendChild(new Label(((String[])data)[0].toString()));
				}elseif (datainstanceof String){
					cell.appendChild(new Label(data.toString()));
				}else {
					cell.appendChild(new Label("UNKNOW:"+data.toString()));
				}
		}
}

实作完成後,可透过 透过 Listbox.setItemRenderer(String) 来指派,或是

<listbox itemRender="quickstart.MyRenderer"/>

<<:  【第十四天 - 堆叠型 SQL注入】

>>:  Day13 AR的处理器发展如何 让我们继续|看|下|去

[Day 02] - Mongo DB环境建置

第二天,首先我打算先把Mongo DB环境建起来 为了方便,就用docker在local部属 Mon...

Azure 管理资源方式比较差异

Azure 管理资源方式比较差异 首先对 Azure 管理资源的方式有个概念,好方便之後介绍 Azu...

Day 27 : Github Actions实作自动化推上Azure

在前一些日子的铁人赛中,我曾经写过关於Docker in Azure的文章,今天我们接续昨天的Git...

虚拟机 Vagrant

第30天了,来聊聊 vm/虚拟机 ... 如果只是想练习Linux的CLI,一定要在GCP上开ins...

Leetcode 挑战 Day 16 [231. Power of Two]

231. Power of Two 今天我们一起挑战leetcode第231题Power of Tw...