@lark.js/mvc 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -116,7 +116,7 @@ creator 函数接收两个参数: store 是 Proxy 代理对象, 可以读写 sta
116
116
 
117
117
  View.extend(props) 创建视图子类, 模板属性 template 引用编译后的 HTML 模板函数, init 方法中通过 useStore(this) 获取 store 实例并绑定视图生命周期, store.observe(this, keys) 声明观察的状态键
118
118
 
119
- 事件方法的方法名格式为 name<eventType>, 例如 increment<click> 对应模板中的 v-click="increment()", 编译时自动编码 View ID, 运行时由 EventDelegator 解析分发
119
+ 事件方法的方法名格式为 name<eventType>, 例如 increment<click> 对应模板中的 @click="increment()", 编译时自动编码 View ID, 运行时由 EventDelegator 解析分发
120
120
 
121
121
  ```typescript
122
122
  import { Router } from "@lark.js/mvc";
@@ -155,15 +155,15 @@ export default View.extend({
155
155
 
156
156
  4. 创建模板
157
157
 
158
- 模板使用 {{}} 语法, = 表示 HTML 转义输出, v-click 等属性绑定事件, 编译时自动将 View ID 和参数编码到事件属性值中
158
+ 模板使用 {{}} 语法, = 表示 HTML 转义输出, @click 等属性绑定事件, 编译时自动将 View ID 和参数编码到事件属性值中
159
159
 
160
160
  ```html
161
161
  <div>
162
162
  <div>{{=count}}</div>
163
- <input type="number" value="{{=step}}" v-change="stepChange()" />
164
- <button v-click="decrement()">-{{=step}}</button>
165
- <button v-click="reset()">Reset</button>
166
- <button v-click="increment()">+{{=step}}</button>
163
+ <input type="number" value="{{=step}}" @change="stepChange()" />
164
+ <button @click="decrement()">-{{=step}}</button>
165
+ <button @click="reset()">Reset</button>
166
+ <button @click="increment()">+{{=step}}</button>
167
167
 
168
168
  {{if history.length > 0}}
169
169
  <ul>
@@ -491,8 +491,8 @@ const frame = {
491
491
 
492
492
  // 子 frameId 映射
493
493
  childrenMap: {
494
- frame_0: "frame_0", // 对应 lark-view="components/counter-store"
495
- frame_1: "frame_1", // 对应 lark-view="components/counter-updater"
494
+ frame_0: "frame_0", // 对应 v-lark="components/counter-store"
495
+ frame_1: "frame_1", // 对应 v-lark="components/counter-updater"
496
496
  },
497
497
 
498
498
  // readyMap 已 ready 的子 frame 集合
@@ -509,7 +509,7 @@ const frame = {
509
509
  - `unmountView()`: 销毁 View 以及所有子 Frame, 清理事件绑定与资源
510
510
  - `mountFrame(frameId, viewPath, viewInitParams?)`: 挂载子 Frame, 复用对象池中的 Frame 或创建新 Frame
511
511
  - `unmountFrame(id?)`: 卸载子 Frame, 归还 Frame 对象到对象池
512
- - `mountZone(zoneId?)` / `unmountZone(zoneId?)`: 管理区域内的 lark-view 子视图, 区域内的子 Frame 在 mountZone 时批量创建
512
+ - `mountZone(zoneId?)` / `unmountZone(zoneId?)`: 管理区域内的 v-lark 子视图, 区域内的子 Frame 在 mountZone 时批量创建
513
513
  - `invoke(name, args?)`: 沿 Frame 树广播方法调用; 如果 View 已渲染则直接调用, 否则加入 invokeList 延迟执行
514
514
  - `children()`: 返回所有子 Frame ID 列表
515
515
  - `parent(level?)`: 获取指定层级的父 Frame
@@ -553,7 +553,7 @@ _视图继承_
553
553
 
554
554
  ```html
555
555
  <button class="btn">只需要写 CSS 类名</button>
556
- <div class="tooltip">不需要写 v-event, 适用于批量绑定</div>
556
+ <div class="tooltip">不需要写 @event, 适用于批量绑定</div>
557
557
  ```
558
558
 
559
559
  事件委托 (viewDelegateEvents): 将 View 的 eventObjectMap 和 eventSelectorMap 注册到 EventDelegator, 全局事件类型 (如 click, change) 绑定到 document.body, 选择器事件通过 matches() API 匹配; 同时处理 window/document 前缀的全局事件 (例如 resize, scroll), 绑定到 window/document
@@ -601,7 +601,7 @@ Updater — 数据绑定与 VDOM diff
601
601
  - 执行 VDOM diff (vdomSetChildNodes) 实际上是真实 DOM diff, 计算最小 DOM 操作集
602
602
  - 调用 `applyIdUpdates()` 批量更新元素 ID
603
603
  - 调用 `applyVdomOps()` 批量执行 DOM 操作
604
- - 通知 Frame 处理新增的 lark-view 子视图 (mountZone)
604
+ - 通知 Frame 处理新增的 v-lark 子视图 (mountZone)
605
605
  3. `updater.snapshot()`: 保存当前数据的 JSON 快照
606
606
  4. `updater.altered()`: 检测数据是否与上次快照不同 (通过 JSON.stringify 比较)
607
607
  5. `updater.get(key?)`: 获取数据, 不传递 key 则返回完整数据对象
@@ -618,14 +618,14 @@ VDOM Diff Engine — 虚拟 DOM (实际上是真实 DOM) 差量比较引擎
618
618
 
619
619
  核心算法:
620
620
 
621
- - `vdomSetNode(oldNode, newNode, parent, ref, frame, keys?)`: 对比单个节点. 先执行 vdomSpecialDiff 处理表单元素, 再通过 isEqualNode 判断节点是否相同. 如果节点类型和名称相同, 则分别对比属性 (vdomSetAttributes) 和子节点 (vdomSetChildNodes); 如果节点类型不同, 则生成 replaceChild 操作. 对于有 lark-view 属性的元素, 如果新旧 view 路径相同则跳过子节点更新, 保护已挂载的子视图
622
- - `vdomSetChildNodes(oldParent, newParent, ref, frame, keys?)`: 对比子节点列表, 支持 keyed diff. 算法: 先从旧子节点构建 keyedNodes 映射 (键由 vdomGetCompareKey 获取, 优先级 id > lark-key > lark-view 路径), 同时统计新子节点的 keyed 计数; 再遍历新子节点, 通过 keyed 匹配查找旧节点, 匹配成功则将旧节点移动到正确位置并递归 diff, 匹配失败则生成 appendChild 操作; 最后移除多余的旧节点
621
+ - `vdomSetNode(oldNode, newNode, parent, ref, frame, keys?)`: 对比单个节点. 先执行 vdomSpecialDiff 处理表单元素, 再通过 isEqualNode 判断节点是否相同. 如果节点类型和名称相同, 则分别对比属性 (vdomSetAttributes) 和子节点 (vdomSetChildNodes); 如果节点类型不同, 则生成 replaceChild 操作. 对于有 v-lark 属性的元素, 如果新旧 view 路径相同则跳过子节点更新, 保护已挂载的子视图
622
+ - `vdomSetChildNodes(oldParent, newParent, ref, frame, keys?)`: 对比子节点列表, 支持 keyed diff. 算法: 先从旧子节点构建 keyedNodes 映射 (键由 vdomGetCompareKey 获取, 优先级 id > ldk > v-lark 路径), 同时统计新子节点的 keyed 计数; 再遍历新子节点, 通过 keyed 匹配查找旧节点, 匹配成功则将旧节点移动到正确位置并递归 diff, 匹配失败则生成 appendChild 操作; 最后移除多余的旧节点
623
623
  - `vdomSetAttributes(oldNode, newNode, ref, keepId?)`: 对比元素属性. 删除新节点中不存在的旧属性, 添加/更新新节点中的属性. id 属性变更记录到 idUpdates 数组而不是直接修改, 因为 id 变更可能影响事件委托. 每次对比前清除 compareKeyCached 缓存
624
624
  - `vdomSpecialDiff(oldNode, newNode)`: 处理 input (value, checked), textarea (value), option (selected) 等特殊元素, 直接同步 DOM 属性值, 绕过 setAttribute
625
625
 
626
- 比较键 (vdomGetCompareKey): 用于 keyed diff 的节点标识, 优先级: id 属性 > lark-key 属性 > lark-view 路径. 有 autoId 标记的元素不使用 id 作为比较键. 比较键结果缓存到元素的 compareKeyCached / cachedCompareKey 属性
626
+ 比较键 (vdomGetCompareKey): 用于 keyed diff 的节点标识, 优先级: id 属性 > ldk 属性 > v-lark 路径. 有 autoId 标记的元素不使用 id 作为比较键. 比较键结果缓存到元素的 compareKeyCached / cachedCompareKey 属性
627
627
 
628
- 静态跳过: 有 lark-key 属性且值相同的元素跳过 diff; 有 lark-attr-key 属性且值相同的元素跳过属性更新
628
+ 静态跳过: 有 ldk 属性且值相同的元素跳过 diff; 有 lak 属性且值相同的元素跳过属性更新
629
629
 
630
630
  DOM 操作编码为数字操作码:
631
631
 
@@ -642,12 +642,12 @@ HTML 解析: `vdomGetNode(html, refNode)` 使用 `document.implementation.create
642
642
 
643
643
  EventDelegator — DOM 事件委托
644
644
 
645
- 所有 DOM 事件委托到 document.body, 通过事件冒泡机制捕获. 每个 View 的 v-event 属性在编译时编码为 viewId\x1ehandlerName(params) 格式, 运行时由 EventDelegator 解析并分发
645
+ 所有 DOM 事件委托到 document.body, 通过事件冒泡机制捕获. 每个 View 的 @event 属性在编译时编码为 viewId\x1ehandlerName(params) 格式, 运行时由 EventDelegator 解析并分发
646
646
 
647
647
  核心机制:
648
648
 
649
649
  - `bind(eventType, selector?)`: 注册事件类型到 document.body, 选择器事件使用事件委托匹配; 同一事件类型只注册一次全局监听器
650
- - `domEventProcessor(event)`: 事件处理入口, 从目标元素向上遍历 DOM 树查找 v-event 属性, 解析得到 View ID 与处理器名称; 解析使用 EVENT_METHOD_REGEX 正则, 捕获 Frame ID (可选), handler 名称, 参数字符串
650
+ - `domEventProcessor(event)`: 事件处理入口, 从目标元素向上遍历 DOM 树查找 @event 属性, 解析得到 View ID 与处理器名称; 解析使用 EVENT_METHOD_REGEX 正则, 捕获 Frame ID (可选), handler 名称, 参数字符串
651
651
  - `findFrameInfo(element)`: View 边界检测, 从目标元素向上查找, 当遇到已绑定的 Frame 元素时停止, 确保事件不会跨 View 传播. 通过 rangeFrameId 属性标记 View 边界, 事件冒泡到边界时停止搜索
652
652
  - `clearRangeEvents(frameId)`: 清除指定 View 范围内的事件标记
653
653
 
@@ -655,7 +655,7 @@ EventDelegator — DOM 事件委托
655
655
 
656
656
  选择器事件: 方法名中 $ 前缀标识选择器事件 (例如 `$menu<hover>`), 编译时将选择器名称编码到 eventSelectorMap, 运行时通过 `element.matches(selector)` API 匹配, 支持 CSS 选择器语法
657
657
 
658
- Range 事件: 通过 lark-view-key 属性标记 View 边界, 事件处理时检查 rangeFrameId, 确保只在对应 View 的 DOM 范围内查找事件处理器
658
+ Range 事件: 通过 lvk 属性标记 View 边界, 事件处理时检查 rangeFrameId, 确保只在对应 View 的 DOM 范围内查找事件处理器
659
659
 
660
660
  Service + Bag — 接口请求管理
661
661
 
@@ -688,7 +688,7 @@ Compiler — 模板编译器
688
688
  第一阶段 — 预处理:
689
689
 
690
690
  - protectComments(): 保护 HTML 注释内的模板语法不被误处理; 将注释替换为 **lark_comment_N** 占位符, 编译完成后恢复
691
- - processViewEvents(): 处理 v-event 属性, 添加 \x1f (VIEW_ID_PLACEHOLDER) 前缀 + \x1e (SPLITTER) 分隔符, 将 JS 对象字面量参数转换为 URL 查询参数格式. 例如: v-click="handlerName({key: 'value'})" 转换为 v-click="\x1f\x1ehandlerName(key=value)"
691
+ - processViewEvents(): 处理 @event 属性, 添加 \x1f (VIEW_ID_PLACEHOLDER) 前缀 + \x1e (SPLITTER) 分隔符, 将 JS 对象字面量参数转换为 URL 查询参数格式. 例如: @click="handlerName({key: 'value'})" 转换为 @click="\x1f\x1ehandlerName(key=value)"
692
692
 
693
693
  第二阶段 — 语法转换:
694
694
 
@@ -800,7 +800,7 @@ updater.digest()
800
800
  │ └── 特殊元素 → 直接同步 value / checked / selected
801
801
  ├── applyIdUpdates() — 批量更新元素 ID
802
802
  ├── applyVdomOps() — 批量执行 DOM 操作
803
- └── Frame 处理 lark-view 子视图 → mountZone
803
+ └── Frame 处理 v-lark 子视图 → mountZone
804
804
  ```
805
805
 
806
806
  对比 React 框架
@@ -809,7 +809,7 @@ updater.digest()
809
809
 
810
810
  React 使用完整的虚拟 DOM 树表示 UI 结构, 通过 JSX 创建 ReactElement 对象树, diff 算法比较新旧两棵虚拟 DOM 树, 生成最小变更集. React 的 diff 算法基于三个假设: 1) 跨层级的节点移动极少, 2) 不同类型的元素产生不同的树, 3) key 属性标识节点的稳定性
811
811
 
812
- Lark 不使用完整的虚拟 DOM 树表示, 而是采用增量式 diff: 新模板渲染生成 HTML 字符串, 通过 document.implementation.createHTMLDocument() 解析为真实 DOM 节点, 然后直接与现有 DOM 树进行 diff. 这意味着 Lark 不需要维护一棵独立的虚拟 DOM 树, 内存占用更低. diff 过程中, Lark 的 vdomSetChildNodes 实现了基于 key 的节点匹配 (通过 id, lark-key, lark-view 属性), 类似于 React 的 key 机制, 但匹配策略更简单: 通过哈希表 (keyedNodes) 一次性构建旧节点的 key 映射, 遍历新节点时查找匹配
812
+ Lark 不使用完整的虚拟 DOM 树表示, 而是采用增量式 diff: 新模板渲染生成 HTML 字符串, 通过 document.implementation.createHTMLDocument() 解析为真实 DOM 节点, 然后直接与现有 DOM 树进行 diff. 这意味着 Lark 不需要维护一棵独立的虚拟 DOM 树, 内存占用更低. diff 过程中, Lark 的 vdomSetChildNodes 实现了基于 key 的节点匹配 (通过 id, ldk, v-lark 属性), 类似于 React 的 key 机制, 但匹配策略更简单: 通过哈希表 (keyedNodes) 一次性构建旧节点的 key 映射, 遍历新节点时查找匹配
813
813
 
814
814
  Lark 的 diff 产生四种操作码 (appendChild=1, removeChild=2, replaceChild=4, insertBefore=8), 批量执行; React 的 diff 产生 patch 列表, 通过 React Reconciler 调度执行. Lark 的 diff 是同步的、全量的 (针对单个 View), React 的 diff 可以通过 shouldComponentUpdate / React.memo 等机制跳过子树
815
815
 
@@ -825,7 +825,7 @@ React 使用不可变数据模型: setState 生成新的状态对象, 触发组
825
825
 
826
826
  事件系统
827
827
 
828
- React 使用合成事件 (SyntheticEvent), 在 React 17+ 将事件委托到根容器节点, 事件对象是原生事件的跨浏览器包装. Lark 使用原生事件委托到 document.body, 通过 v-event 属性编码 View ID 和 handler 名称, EventDelegator 解析分发. Lark 的方案更轻量, 不需要额外的事件对象池和兼容层
828
+ React 使用合成事件 (SyntheticEvent), 在 React 17+ 将事件委托到根容器节点, 事件对象是原生事件的跨浏览器包装. Lark 使用原生事件委托到 document.body, 通过 @event 属性编码 View ID 和 handler 名称, EventDelegator 解析分发. Lark 的方案更轻量, 不需要额外的事件对象池和兼容层
829
829
 
830
830
  对比 Vue3 框架
831
831
 
@@ -833,7 +833,7 @@ React 使用合成事件 (SyntheticEvent), 在 React 17+ 将事件委托到根
833
833
 
834
834
  Vue3 的模板编译器将单文件组件的 <template> 编译为渲染函数, 编译过程分为三步: parse (模板 → AST), transform (AST → JavaScript AST), generate (JavaScript AST → 渲染函数代码). Vue3 的编译器实现了静态提升 (Static Hoisting): 将静态节点提升到渲染函数外部, 避免每次渲染重新创建; PatchFlag 标记动态节点, diff 时只比较标记为动态的部分; Block Tree 优化, 将模板按结构化指令 (v-if, v-for) 拆分为 Block, diff 时扁平化遍历
835
835
 
836
- Lark 的模板编译器将 {{}} 语法编译为 JS 函数, 编译过程分为三步: 预处理 (protectComments + processViewEvents), 语法转换 (convertArtSyntax: {{}} → <% %>), 函数生成 (compileToFunction: <% %> → 箭头函数). Lark 的编译器没有 AST 中间表示, 直接通过正则匹配和字符串替换完成转换. Lark 不实现静态提升, 每次渲染完整执行模板函数; 也没有 PatchFlag, 每次渲染产生的 HTML 需要完整 diff. Lark 通过 lark-keylark-attr-key 属性提供手动静态跳过能力, 类似于 Vue3 PatchFlag 的手动版本
836
+ Lark 的模板编译器将 {{}} 语法编译为 JS 函数, 编译过程分为三步: 预处理 (protectComments + processViewEvents), 语法转换 (convertArtSyntax: {{}} → <% %>), 函数生成 (compileToFunction: <% %> → 箭头函数). Lark 的编译器没有 AST 中间表示, 直接通过正则匹配和字符串替换完成转换. Lark 不实现静态提升, 每次渲染完整执行模板函数; 也没有 PatchFlag, 每次渲染产生的 HTML 需要完整 diff. Lark 通过 ldklak 属性提供手动静态跳过能力, 类似于 Vue3 PatchFlag 的手动版本
837
837
 
838
838
  Vue3 的编译器输出 render() 函数, 返回虚拟 DOM 节点树 (VNode), 再由运行时进行 diff; Lark 的编译器输出模板函数, 返回 HTML 字符串, 由 Updater 解析为真实 DOM 后再 diff. Vue3 的编译时优化更丰富, Lark 的编译器更简洁, 依赖运行时 diff 的 keyed 匹配来保证性能
839
839
 
@@ -855,7 +855,7 @@ Lark 的 Store 模块同样基于 Proxy 实现响应式, 核心是 createState()
855
855
 
856
856
  组件模型
857
857
 
858
- Vue3 使用单文件组件 (SFC) 组织视图, <template>, <script>, <style> 放在同一个 .vue 文件中; Lark 将模板 (.html) 和逻辑 (.ts) 分离, 通过 import 关联. Vue3 组件通过 props 接收父组件数据, 通过 emit 向父组件发送事件; Lark View 通过 lark-view 属性传递路径参数, 通过 {{@}} 引用查找传递对象引用, 通过 Frame.invoke 跨层级通信
858
+ Vue3 使用单文件组件 (SFC) 组织视图, <template>, <script>, <style> 放在同一个 .vue 文件中; Lark 将模板 (.html) 和逻辑 (.ts) 分离, 通过 import 关联. Vue3 组件通过 props 接收父组件数据, 通过 emit 向父组件发送事件; Lark View 通过 v-lark 属性传递路径参数, 通过 {{@}} 引用查找传递对象引用, 通过 Frame.invoke 跨层级通信
859
859
 
860
860
  Vue3 的组合式 API (Composition API) 通过 setup() 函数组织逻辑, 使用 ref, reactive, computed, watch 等 API; Lark 的 defineStore creator 函数类似于 setup(), 在其中定义 state 和 handler. Vue3 使用 provide/inject 跨层级传递数据; Lark 使用 State (全局单例) 和 Store (按需创建) 实现跨视图数据共享
861
861
 
@@ -882,7 +882,7 @@ Store API
882
882
 
883
883
  View 事件绑定
884
884
 
885
- 模板中通过 v-事件类型 属性绑定事件, 格式为 v-click="handlerName()". 支持传参: v-click="handlerName({key: value})", JS 对象字面量参数会自动转换为 URL 查询参数格式. 编译时自动编码 View ID 与参数, 运行时由 EventDelegator 解析分发
885
+ 模板中通过 @事件类型 属性绑定事件, 格式为 @click="handlerName()". 支持传参: @click="handlerName({key: value})", JS 对象字面量参数会自动转换为 URL 查询参数格式. 编译时自动编码 View ID 与参数, 运行时由 EventDelegator 解析分发
886
886
 
887
887
  模板语法
888
888
 
@@ -14638,17 +14638,17 @@ function restoreComments(source, comments) {
14638
14638
  }
14639
14639
  function processViewEvents(source) {
14640
14640
  return source.replace(
14641
- /v-(\w+)="([^"]+)"/g,
14641
+ /@(\w+)="([^"]+)"/g,
14642
14642
  (fullAttr, eventName, attrValue) => {
14643
14643
  const eventMatch = attrValue.match(/^(\w+)\((.*)\)$/s);
14644
14644
  if (!eventMatch) return fullAttr;
14645
14645
  const handlerName = eventMatch[1];
14646
14646
  const paramsStr = eventMatch[2].trim();
14647
14647
  if (!paramsStr) {
14648
- return `v-${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER}${handlerName}()"`;
14648
+ return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER}${handlerName}()"`;
14649
14649
  }
14650
14650
  const urlParams = jsObjectToUrlParams(paramsStr);
14651
- return `v-${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER}${handlerName}(${urlParams})"`;
14651
+ return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER}${handlerName}(${urlParams})"`;
14652
14652
  }
14653
14653
  );
14654
14654
  }
@@ -14874,12 +14874,12 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
14874
14874
  const last = blockStack.pop();
14875
14875
  if (!last) {
14876
14876
  throw new Error(
14877
- `[@lark/mvc error(template] unexpected {{${code}}}: no matching open block`
14877
+ `[@lark/mvc error] unexpected {{${code}}}: no matching open block`
14878
14878
  );
14879
14879
  }
14880
14880
  if (last.ctrl !== expectedCtrl) {
14881
14881
  throw new Error(
14882
- `[@lark/mvc error(template] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
14882
+ `[@lark/mvc error] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
14883
14883
  );
14884
14884
  }
14885
14885
  return `${debugPrefix}<%}%>`;
@@ -15239,19 +15239,18 @@ var BUILTIN_GLOBALS = {
15239
15239
  // Reference lookup: (refData, value) => key
15240
15240
  // Finds or allocates a SPLITTER-prefixed key in refData for a given
15241
15241
  // object reference. Used by {{@ref}} operator for passing object
15242
- // references to child views via lark-view attributes.
15243
- // Aligned with mx.js Updater_Ref.
15242
+ // references to child views via v-lark attributes.
15244
15243
  $i: 1,
15245
15244
  // URI encoder: v => encodeURIComponent($n(v)).replace(/[!')(*]/g, extraMap)
15246
15245
  // Extends encodeURIComponent with encoding of ! ' ( ) *.
15247
- // Applied to values in v-event URL parameters and {{!uri}} contexts.
15246
+ // Applied to values in @event URL parameters and {{!uri}} contexts.
15248
15247
  $eu: 1,
15249
15248
  // Quote encoder: v => $n(v).replace(/['"\\]/g, '\\$&')
15250
15249
  // Escapes quotes and backslashes for safe embedding in HTML attribute
15251
15250
  // values (e.g. data-json='...').
15252
15251
  $eq: 1,
15253
15252
  // View ID — the unique identifier of the owning View instance.
15254
- // Injected into v-event attribute values at render time so that
15253
+ // Injected into @event attribute values at render time so that
15255
15254
  // EventDelegator can dispatch events to the correct View handler.
15256
15255
  // The \x1f placeholder in compiled output is replaced with '+$viewId+'.
15257
15256
  $viewId: 1,