我所拥有的组件具有 N 个过滤器,对于每个过滤器,都有 M 个值。我试图动态显示这两个,但似乎没有用。
我能够测试这些值,并查看我是否使用了正确的语法来检索数据,并且代码能够从对象中获取数据。但是,使用动态过滤器时,似乎没有任何东西可以通过下拉<button>
标签。
您可以查看here,这是我作为应用程序副本制作的StackBlitz项目。
我已经以从HTML调用getFilters
时返回的形式将过滤器对象打印到控制台。如您所见,它正在返回数据,但是当用户单击下拉列表时,看不到任何filterValues。
我希望它显示每个filterValues
,但是当我单击下拉按钮时,什么也没有发生。如果从其中删除动态功能,则可以在下拉列表中看到值,但我希望它是动态的。任何帮助将不胜感激。
相关模板代码:
<div ngbDropdown class="d-inline-block" *ngFor="let filter of getFilters()">
<button class="btn btn-outline-primary" id="{{filter[0]-dropdown}}" ngbDropdownToggle>{{filter[1].displayName}}</button>
<div ngbDropdownMenu attr.aria-labelledby="{{filter[0]-dropdown}}">
<button ngbDropdownItem *ngFor="let val of filter[1].filterValues">{{val}}</button>
</div>
</div>
和相关的TypeScript代码:
getFilters() : [string, FilterItem][] {
...
return Array.from(this.filters.entries());
}
答案 0 :(得分:1)
您看到的问题是由于您的getFilters()
函数不是幂等的。
Angular期望,如果它连续两次调用一个方法而无需用户干预,它将返回相同的值。如果您的函数返回一个数组,则需要返回两次相同的数组。但是在您的代码中,每次返回一个不同的数组(即使它具有相同的内容,仍然是一个不同的引用)。
尝试使用getFilters()
方法的此实现,您会发现问题消失了(我不建议您像这样解决您的问题,但是它可以说明问题出在哪里):
private cached;
getFilters() : [string, FilterItem][] {
if (!this.cached)
this.cached = Array.from(this.filters.entries())
return this.cached;
}
我不建议这样缓存值,相反,应该将更改应用程序状态的代码放在与检索应用程序状态的代码不同的部分中,例如:
constructor () {
this.filters = ...
this.filterEntries = Array.from(this.filters.entries());
}
然后在您的模板中:
<div ngbDropdown class="d-inline-block" *ngFor="let filter of filterEntries">
Angular docs告诉您以下有关副作用的信息,我将最相关的文字加粗了:
没有明显的副作用
除目标属性的值外,模板表达式不应更改任何应用程序状态。
用Angular术语来说,幂等表达式总是返回完全相同的东西,直到其依赖值之一改变为止。
如果幂等表达式返回字符串或数字,则当连续调用两次时,它将返回相同的字符串或数字。 如果表达式返回一个对象(包括数组),则当它连续两次被调用时,它将返回相同的对象引用。