使用Ember计算属性过滤模型,ember-models-table无数据显示问题
Hey there! Let's work through those two filtering issues you're hitting with ember-models-table 2—they're pretty common when mixing Ember computed properties with this component, so let's break down the fixes step by step:
1. Ensure your computed property returns the correct data type
ember-models-table expects the data prop to be an Ember.ArrayProxy instance or a native JavaScript array—not an unresolved Promise or a non-array value. If your model is a DS.RecordArray (common with Ember Data), convert it to a native array first to avoid filtering glitches:
// ❌ Problematic: Might return an unfiltered or non-array value if model is async filteredUsers: computed('model.@each.isActive', 'currentFilter', function() { return this.model.filter(user => user.isActive === this.currentFilter); }) // ✅ Fixed: Convert RecordArray to a native array and handle async safely filteredUsers: computed('model.@each.isActive', 'currentFilter', function() { const users = this.model.toArray(); // Guarantees we're working with a real array const targetIsActive = this.currentFilter === true; // Match your filter's data type! return users.filter(user => user.get('isActive') === targetIsActive); })
2. Fix type mismatches between filter values and data fields
From your partial HBS snippet, it looks like you're using a select dropdown for filtering. A super common gotcha here is that select values are strings (like "true" instead of true), while your isActive field is probably a boolean. This mismatch makes your filter return empty even when you think it's working:
Updated HBS code (filling in your partial snippet):
<div class="form-group"> <label for="show">Show:</label> <select class="form-control" id="show" value={{this.currentFilter}} {{on "change" (fn (mut this.currentFilter))}} > <option value="true">Active Users</option> <option value="false">Inactive Users</option> </select> </div> {{models-table data=this.filteredUsers columns=this.columns }}
Fix type conversion in your computed property:
filteredUsers: computed('model.@each.isActive', 'currentFilter', function() { // Convert string filter value to boolean to match isActive's data type const targetIsActive = this.currentFilter === 'true'; return this.model.toArray().filter(user => user.get('isActive') === targetIsActive); })
3. Make sure filter changes trigger computed property updates
If you're using Ember Octane or newer, mark currentFilter as a tracked property so changes automatically trigger your computed property to recalculate:
import { tracked } from '@glimmer/tracking'; import { computed } from '@ember/object'; import Controller from '@ember/controller'; export default class UsersController extends Controller { @tracked currentFilter = 'true'; // Tracked property ensures updates fire @computed('model.@each.isActive', 'currentFilter') get filteredUsers() { const targetIsActive = this.currentFilter === 'true'; return this.model.toArray().filter(user => user.isActive === targetIsActive); } }
4. Disable built-in filtering if it's conflicting
ember-models-table has its own built-in filtering feature. If you're using a custom computed property filter, the built-in one might override your results. Disable it explicitly:
{{models-table data=this.filteredUsers columns=this.columns enableFiltering=false }}
If none of these fixes work, pop open your browser console and log this.filteredUsers to confirm it actually contains data after filtering. Sometimes the issue is just a tiny typo in your filter logic that's easy to miss!
内容的提问来源于stack exchange,提问作者Sow Hari

