Files
endorphin-tessera-gui/examples/property-bindings.endor
T

46 lines
2.8 KiB
Plaintext

// 通用属性绑定:业务 Model 的三个零参只读方法分别计算 rect.width、rect.color 和 label.text。
// 绑定在目标隐藏时也会更新;两个页面共享同一组 Block,不需要两份模型。
// width/color/label 是唯一业务来源,绑定计算只读,expand 是显式事件写入入口。
class Model {
// 三个业务值由下面三个 getter 分别读取;绑定的目标属性保存在视觉对象上,业务修改入口在 expand。
width: Number
color: String
label: String
// 绑定求值调用此零参 getter 并取得 Number;结果写入 rect.width,布局读取时仍须符合有限尺寸范围。
function getWidth(self: Model): Number { return self.width }
// 返回颜色文本;依赖只包含实际读取的模型属性。
function getColor(self: Model): String { return self.color }
// 返回当前说明文字,供 TextBlock.text 绑定使用。
function getLabel(self: Model): String { return self.label }
// 一个事件同时改三个属性,随后绑定传播,布局与绘制在完整刷新后发布。
function expand(self: Model, event: Event): Unit {
// 由 clickConnection 派发调用,可写业务状态;三个 getter 则由绑定求值调用,不能反向修改模型。
self.width = 260
self.color = "#237A45"
self.label = "绑定已更新"
}
}
model = Model(120, "#526AC7", "点击更新共享对象")
// 原生构造给初始载荷,后面的 bind 再把这些属性接到模型;label 的初始化字符串也会被绑定结果替换。
rect = RectBlock(120, 40, 8, "#526AC7")
label = TextBlock("初始化")
// 保存三个可断开的绑定令牌;令牌不强持有隐藏目标,目标仍需由业务对象图保留。
widthBinding = rect.bind("width", model.getWidth)
// 每次传入的是已绑定 model 的零参函数,注册不会调用 expand,也不把方法名当作待执行源码字符串。
colorBinding = rect.bind("color", model.getColor)
labelBinding = label.bind("text", model.getLabel)
button = Button("更新宽度、颜色和文字")
clickConnection = button.on("click", model.expand)
root = Column(24, 16, label, rect, button)
// 两个页面共享 root 及其子对象,因此只有一组属性绑定,不需要为每个 Mount 再注册一组。
// 两页同属一个窗口,本例最终仅激活第一页;同时跨窗口显示的传播由宿主测试另外覆盖。
page = Page()
page.title = "通用属性绑定"
page.render(root)
// 第二页面使用同一根容器,切页只更换 Mount 展示上下文;最后 activate 回第一页面。
second = Page()
second.title = "同一组 Block"
second.render(root)
// 切回第一页不销毁第二页或重建模型;隐藏页仍引用同一组更新后的业务/视觉对象。
page.activate()