Ember中如何渲染过滤@argument传入的数据集并更新each循环?
核心原因
Ember 中 @ 开头的是父组件传入的只读参数,子组件没有权限直接修改赋值,所以你尝试直接修改@data的写法不会生效。
可行实现方案
方案1:过滤逻辑上移到父组件(适合过滤结果需要同步给其他关联组件的场景)
子组件不持有数据修改权限,仅把过滤条件/过滤结果传递给父组件,由父组件更新数据源,触发子组件重渲染。
代码示例:
- 子组件的点击事件回调父组件传入的更新方法:
// 子组件逻辑文件 @action changeProject(projectName) { const filteredResult = this.args.data.filter(item => item.name === projectName); // 调用父组件传入的更新action this.args.onFilterFinish(filteredResult); }
- 父组件调用子组件时传入对应更新方法:
<!-- 父组件模板 --> <YourComponent @data={{this.originData}} @onFilterFinish={{this.updateData}} />
// 父组件逻辑文件 @action updateData(filteredData) { this.originData = filteredData; }
方案2:子组件本地维护过滤状态(适合过滤仅在当前组件生效的场景)
在子组件内部用tracked变量存储过滤条件,通过计算属性返回最终要渲染的列表,不需要修改父组件传入的@data。
代码示例:
- 子组件逻辑:
// 子组件逻辑文件 import { tracked } from '@glimmer/tracking'; import { cached } from '@glimmer/tracking'; export default class YourComponent extends Component { // 存储选中的项目名称作为过滤条件 @tracked selectedProject = null; // 缓存过滤后的列表,仅当@data或selectedProject变化时重新计算,老版本Ember无cached可直接去掉不影响功能 @cached get renderList() { if (!this.selectedProject) return this.args.data; return this.args.data.filter(item => item.name === this.selectedProject); } @action changeProject(projectName) { this.selectedProject = projectName; } }
- 修改子组件模板,循环本地计算出的渲染列表:
{{#each this.renderList as |project|}} <ItemList @categories={{project.category}}/> {{/each}}
- 按钮点击事件简化:
<li class="inline hover:underline cursor-pointer ml-4" {{on "click" (fn this.changeProject project.name)}} > {{project.name}} </li>
内容的提问来源于stack exchange,提问作者NullVoxPopuli
相关产品推荐
相关产品推荐

