53 lines
2.6 KiB
Plaintext
53 lines
2.6 KiB
Plaintext
// 测量与绘制依赖分离:改颜色应复用尺寸缓存,改模型宽度才需要重新测量。
|
|
// ViewportBand 还显式读取实际页面视口,使原生 resize 可通过依赖触发重测。
|
|
// 只负责测量需要的宽度,和绘制颜色分成两个业务对象以便观察独立失效。
|
|
class WidthModel {
|
|
width: Number
|
|
// 点击把模型宽度置为 260;源 measure 读取过该字段,缓存因此失效。
|
|
function expand(self: WidthModel, event: Event): Unit {
|
|
self.width = 260
|
|
}
|
|
}
|
|
// 保存 paint 使用的颜色,不参与 CachedRect 的测量。
|
|
class Tint {
|
|
color: String
|
|
// 只改颜色;正常情况下需重绘而不重新执行无关源测量。
|
|
function blue(self: Tint, event: Event): Unit {
|
|
self.color = "#526AC7"
|
|
}
|
|
}
|
|
// 原生矩形的尺寸/颜色策略分别由源协议覆盖,业务模型通过字段持有。
|
|
class CachedRect: RectBlock {
|
|
dimensions: WidthModel
|
|
tint: Tint
|
|
// 读取 dimensions.width 返回固定高 60;实际读观察由运行时缓存记录,不手工声明依赖表。
|
|
function measure(self: CachedRect, mount: Mount, constraints: Constraints): MeasureResult {
|
|
return MeasureResult(self.dimensions.width, 60)
|
|
}
|
|
// 复用原生矩形命令,再改新命令的颜色;修改新结果被允许,但 paint 不能修改已有业务对象。
|
|
function paint(self: CachedRect, mount: Mount, geometry: Bounds): DisplayList {
|
|
drawing = RectBlock.paint(self, mount, geometry)
|
|
drawing.commands.at(0).color = self.tint.color
|
|
return drawing
|
|
}
|
|
}
|
|
// 宽度来自 ui.viewport 的当前逻辑页面区域,显示窗口变化也能成为测量依赖。
|
|
class ViewportBand: RectBlock {
|
|
// 返回可用视口宽度,最终仍服从父容器约束;外层 padding 会减少分配宽度。
|
|
function measure(self: ViewportBand, mount: Mount, constraints: Constraints): MeasureResult {
|
|
return MeasureResult(ui.viewport().width, 24)
|
|
}
|
|
}
|
|
// 创建相互独立的宽度/颜色模型并绑定两个按钮,用相同对象观察缓存与可见结果。
|
|
dimensions = WidthModel(200)
|
|
tint = Tint("#ED6A5A")
|
|
rect = CachedRect(80, 20, 0, "#ED6A5A", dimensions, tint)
|
|
band = ViewportBand(80, 24, 0, "#237A45")
|
|
blue = Button("只改绘制颜色")
|
|
expand = Button("修改测量依赖")
|
|
blueConnection = blue.on("click", tint.blue)
|
|
expandConnection = expand.on("click", dimensions.expand)
|
|
root = Column(24, 16, TextBlock("改变颜色保留测量缓存;改变宽度重新测量"), band, rect, blue, expand)
|
|
page = Page()
|
|
page.render(root)
|