Archived
fix(interaction): data-options 收尾防重改认显式标记,不再靠「有没有 selected 这个词」
评审复现了一个真泄漏:selectCurrent 用 /\bselected\b/.test(block) 当「行内那一遍 处理过没有」的代理 —— 而一行被正确处理过、且合法地落在「没有选中项」上(值不在 选项里,或这一格还没填),跟「压根没被处理过」在字面上是同一个样子。renderView 收尾那一遍拿外层作用域重新处理这块,若外层恰好有个同名裸键命中某个选项,就会把 它错误地渗进这一行 —— 界面撒谎:显示一个这一行数据里根本不存在的选中态。 改记一个跟内容无关的标记属性 data-sel-scoped:处理完(不管有没有真标出 selected) 都打上,下一遍见到标记就跳过;renderView 收尾前把它整个剥掉,不留进交给沙箱的成品。 顺带治了评审点的 Minor #1:旧写法还会被 <option> 显示文字里恰好出现的 "selected" 误判(枚举标签写成 "Selected Value" 那种)。 三条新用例:行内下拉值不在选项里 / 新加的空行,均验证不再被外层同名值渗透 (RED 证实了泄漏确实发生过);行外独立下拉仍正确标好 selected(防重归防重, 不能把本该工作的那条也防没了)。 docs/HTML报告生成规范.md 补一句:data-options 与 data-slot 不能共存,后者会被 fillOptions 摘掉不起作用(评审 Minor #2)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
This commit is contained in:
@@ -477,4 +477,33 @@ describe('data-options:下拉的选项从台账现读', () => {
|
||||
expect(out.match(/<option value="1">DC-DC 降压稳压器<\/option>/g)).toHaveLength(1);
|
||||
expect(out.match(/<option value="1" selected>DC-DC 降压稳压器<\/option>/g)).toHaveLength(1);
|
||||
});
|
||||
|
||||
/*
|
||||
* 评审逮到的渗透:「块里有没有 selected 这个词」防不住重复处理 ——
|
||||
* 一行被正确处理过、且合法地落在「没有选中项」上(值不在选项里 / 这一格还没填),
|
||||
* 跟「压根没被处理过」在字面上是同一个样子:都没有 selected 这个词。
|
||||
* `renderView` 收尾那一遍拿的是外层作用域,这里的外层 `chip_type_id: 2` 恰好命中
|
||||
* 选项列表里的 LDO —— 若防重失灵,它会被错误地渗进这一行,而这一行自己的数据
|
||||
* 说的明明是「没有选中」。
|
||||
*/
|
||||
const rowHtml =
|
||||
'<tbody data-rows="mine:a.b" data-edit="a.b">' +
|
||||
'<tr><select data-col="chip_type_id" data-slot="chip_type_id" data-options="parts.chip_type" data-option-value="type_id" data-option-label="type_name"></select></tr>' +
|
||||
'</tbody>';
|
||||
|
||||
it('行内下拉:该行的值不在选项里 —— 不许被外层同名的值渗进来标 selected', () => {
|
||||
const out = renderView(rowHtml, { ...scope, 'mine:a.b': [{ chip_type_id: 99 }] });
|
||||
expect(out).not.toContain('selected');
|
||||
});
|
||||
|
||||
it('行内下拉:新加的空行(这一列还没填)—— 同样不许被外层同名的值渗进来', () => {
|
||||
const out = renderView(rowHtml, { ...scope, 'mine:a.b': [{}] });
|
||||
expect(out).not.toContain('selected');
|
||||
});
|
||||
|
||||
it('行外的独立下拉仍按顶层作用域正确标好 selected(防重不能把这条也防没了)', () => {
|
||||
const html = '<select data-col="chip_type_id" data-slot="chip_type_id" data-options="parts.chip_type" data-option-value="type_id" data-option-label="type_name"></select>';
|
||||
const out = renderView(html, scope);
|
||||
expect(out).toContain('<option value="2" selected>LDO 线性稳压器</option>');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user