关于Ember 3条件语句的渲染与编译异常问题咨询
你的Ember 3模板出现这两个条件渲染问题的根源解析
作为经常跟Ember模板打交道的开发者,我一眼就能看出这俩问题都是Handlebars模板引擎对HTML结构完整性的严格校验导致的,逐个给你拆解:
问题1:渲染出空<ol></ol>在列表前,实际列表无闭合标签
这种情况100%是你把<ol>的开始标签和结束标签拆到了不同的条件块里,比如写了类似这样的代码:
{{#if showList}} <ol> {{/if}} {{#each model.items as |item|}} <li>{{item.text}}</li> {{/each}} {{#if showList}} </ol> {{/if}}
Handlebars在解析模板时,会检查每个代码块内的HTML是否完整。当它处理第一个{{#if}}块时,看到<ol>没有在同一个块内闭合,就会自动补全一个</ol>,所以先输出了空的<ol></ol>。而后面的</ol>因为找不到对应的未闭合开始标签,直接被渲染引擎忽略,最终就出现了列表前有个空列表标签、实际内容却没被包裹的诡异情况。
问题2:编译报错Error: Unclosed element ol (on line 2)
这个是编译阶段的结构校验不通过,原因很明确:
- 要么你写了
<ol>开始标签,但没写对应的闭合标签; - 要么闭合标签被放在了一个编译时无法确定会执行的分支里(比如另一个条件块),导致模板的静态结构看起来不合法。
举个典型的错误写法:
{{#if showList}} <ol> {{/if}} <li>Test item</li> </ol>
编译时,Handlebars会扫描整个模板的HTML结构,发现有一个</ol>标签,但对应的<ol>只在条件块里——编译阶段引擎没法预知showList的真假,它要求模板的静态结构必须是合法的HTML,所以直接抛出“未闭合元素ol”的错误。
正确写法参考
要避免这些问题,你应该把整个<ol>(包括里面的列表项循环)都放在同一个条件块中:
{{#if showList}} <ol> {{#each model.items as |item|}} <li>{{item.text}}</li> {{/each}} </ol> {{/if}}
这样既保证了HTML结构的完整性,编译和渲染都不会出问题。
内容的提问来源于stack exchange,提问作者ajeh
相关产品推荐
相关产品推荐

