使用计算的 aurelia 搜索过滤在渲染到视图时会导致问题
Posted
技术标签:
【中文标题】使用计算的 aurelia 搜索过滤在渲染到视图时会导致问题【英文标题】:aurelia search filtering using a computed is causing issues when rendering to view 【发布时间】:2017-10-15 17:03:57 【问题描述】:我有一个检索对象的搜索功能
this.searchForObjectByName = () =>
this.server.get('objects/?searchTerm=' + self.searchTerm)
.then(groupObjects=>
this.searchResults = groupObjects;
);
然后我将这个结果设置为一个名为 searchResults 的属性,它是一组对象。 我现在想根据结果执行一些过滤。假设我有一些看起来像这样的对象组:
id: 1,
name: 'group 1',
objects: [
id: 1,
name: 'object name 1',
categories: ['Cat A', 'Cat B']
,
id: 2,
name: 'object name 2',
categories: ['Cat A', 'Cat D']
,
id: 3,
name: 'object name 3',
categories: ['Cat C', 'Cat D']
]
,
id: 2,
name: 'group 2',
objects: [
id: 4,
name: 'object name 4',
categories: ['Cat A', 'Cat F']
,
id: 5,
name: 'object name 5',
categories: ['Cat C', 'Cat D']
]
然后我想过滤以仅显示 Cat A 对象。 我有一个根据所选类别过滤搜索结果的计算:
get filteredSearchResults(): any[]
var filteredGroups = this.searchResults.map(res =>
let filteredGroup = new Group;
filteredGroup = res.id,
filteredGroup = res.name;
filteredGroup = res.objects.filter(o => this.filteredCategories.some(fc => o.categories.some(oc => oc == fc)));
return filteredGroup;
);
filteredGroups = filteredGroups.filter(fg => fg.objects.length > 0);
return filteredGroups;
这可以很好地过滤结果,我可以选择不同的类别并正确过滤。然而,它在 UI 中到处乱跳,由于使用计算过滤结果,结果会不断更新。我不能使用 computedfrom 属性,因为它基于我选择的过滤类别(即一个数组)和从服务器返回的结果(也是一个数组)。以前有没有其他人遇到过这个问题?我尝试的每件事都会导致抖动,我不确定如何以不同的方式做到这一点。
我可以在所选类别发生变化或从服务器返回数据时触发事件,然后我可以重新计算过滤结果。这可以工作,但很hacky,并且希望能够在计算中做到这一点
【问题讨论】:
【参考方案1】:如果没有 computedFrom,您的属性 getter 将被轮询,这就是您的界面跳来跳去的原因。我不熟悉 .some,但我猜无法保证顺序。虽然您可以简单地订购搜索结果来解决这个问题,但每 5 秒过滤和排序一个数组会非常低效。
使用集合观察器,您的过滤器代码只会在您的接口过滤器实际更改时执行。 我还没有实际测试过这段代码
import BindingEngine, Disposable, bindable from 'aurelia-framework';
export class MyPage
@bindable searchTerm: string;
filteredSearchResults: any[];
subscription: Disposable;
constructor(private bindingEngine: BindingEngine)
attached()
this.subscription = this.bindingEngine.collectionObserver(this.filteredCategories).subscribe(this.filtersChanged);
detached()
this.subscription.dispose();
searchTermChanged(newValue: string, oldValue: string)
this.find();
find()
this.server.get('objects/?searchTerm=' + this.searchTerm)
.then(groupObjects=>
this.searchResults = groupObjects;
this.update();
);
update()
// your original filtering logic unchanged
var filteredGroups = this.searchResults.map(res =>
let filteredGroup = new Group;
filteredGroup = res.id,
filteredGroup = res.name;
filteredGroup = res.objects.filter(o => this.filteredCategories.some(fc => o.categories.some(oc => oc == fc)));
return filteredGroup;
);
filteredGroups = filteredGroups.filter(fg => fg.objects.length > 0);
// set value instead of using a computed property
this.filteredSearchResults = filteredGroups;
filtersChanged(splices)
this.update(); // you could remove this method and bind the array observable directly to update()
【讨论】:
这有点像我当前的工作实现,但这里的问题是如果我执行另一个搜索说我搜索“对象 3”,那么过滤的结果不会更新,因为没有观察到搜索结果属性。我使用 eventAggregator 发布了一个名为“filterSearchResults”的事件,并有一个订阅可以执行您对 filtersChanged 回调的建议。每次我想更新结果时,我只需要发布事件。我觉得这两种方法都不理想,因为它的可扩展性不太好(更多过滤器等),顺便说一句,感谢您的回复! 在这种情况下,您希望将客户端过滤逻辑移动到另一个方法,并且您的 filtersChanged 回调以及服务器 get 可以执行相同的功能。事件聚合器是创建松散耦合组件的一个很好的解决方案,但是在单个组件内部使用它并没有多大意义。我会更新我的答案以反映这一点。 我会接受答案,即使我希望它可以以某种方式使用计算属性。我要做的是扩展 collectionObserver 以获取一组要观察的项目,因此我只需将其设置在一个地方。以上是关于使用计算的 aurelia 搜索过滤在渲染到视图时会导致问题的主要内容,如果未能解决你的问题,请参考以下文章
typescript Bulma.io形式为aurelia和aurelia形式的渲染器。