我正在尝试在我的项目中实现PrimeNg AutoComplete控件。
我指的是PrimeNg
这些是我遵循的步骤。
1。添加了模块。
import { AutoCompleteModule } from 'primeng/autocomplete';
2。导入的模块
imports: [CommonModule, FormsModule, AutoCompleteModule],
第3。创建字符串数组。
brands: string[] = ['Audi', 'BMW', 'Fiat', 'Ford', 'Honda', 'Jaguar', 'Mercedes', 'Renault', 'Volvo', 'VW'];
4。添加了p模板
<p-autoComplete [(ngModel)]="brand" [suggestions]="this.brands" (completeMethod)="search($event)" [size]="30 [minlength]="1" placeholder="Tags"></p-autoComplete>
在运行项目视图已加载但是当我开始在文本框中键入时,虽然加载gif可见,但仍未加载建议。
控制台没有错误。
在询问之前我查看了所有博客和文档,但没有找到任何解决方案。
我有什么遗漏的!
非常感谢任何帮助。
答案 0 :(得分:4)
供将来参考,
最初我认为(completeMethod)属性如果我按原样返回建议数组就不会有任何影响。但是我们需要的是每次我们在文本框中输入文本时,Suggestion数组必须更改必须有一个新的引用。
以下是文档中的快照。
https://www.primefaces.org/primeng/#/autocomplete
更改检测
AutoComplete使用基于setter的检查或ngDoCheck来实现建议是否已更改以更新UI。这是使用immutable属性配置的,当启用(默认)基于setter的检测时,因此您的更改(如添加或删除记录)应始终创建新的数组引用而不是操作现有数组,因为Angular不会触发setter(如果引用)不会改变。例如,在删除项目时使用切片而不是拼接,或者在添加项目时使用展开运算符而不是推送方法。另一方面,将immutable属性设置为false可以通过使用带有IterableDiffers的ngDoCheck来监听更改,而无需创建新的数据引用,从而消除了此限制。基于Setter的方法更快,但根据您的偏好可以使用这两种方法。
答案 1 :(得分:0)
我通过重新分配自动完成对象的.suggestions并每次调用show来缓解此问题。您可能可以将this.unfilteredResults直接分配给.suggestions。我知道这目前在v6.x中有效。
[ { store_id: 472, product_id: 456456, city: 'Delhi' },
{ store_id: 489, product_id: 123123, city: 'Delhi' } ]
答案 2 :(得分:0)
我在下面做了操作以解决我的问题。我正在使用this.result = data
。哪个没有用,所以我更改了它:
this.backendService.getSiteList(this.query).subscribe(data => {
this.results = [...data];
});
答案 3 :(得分:0)
此答案不会解决您的特定问题,但对于从网络服务器加载建议时未出现建议的任何人来说,它都很有用。
我们有一份包含 20,000 只基金的清单。用户可以输入几个字符,然后我们调用网络服务来获取匹配列表。
这一切都很好,Chrome 的开发人员工具向我展示了结果正在加载......但 PrimeNG 的建议中没有出现任何内容。
现在,棘手的一点...
在我的 Angular 应用中,如果我将结果存储在“this.fundSuggestions
”中,则一切正常。
export class FundComponent {
fundSuggestions:KeyValue[];
chosenFund:KeyValue;
. . .
}
我的自动完成看起来像这样:
<p-autoComplete
[(ngModel)]="chosenFund"
[suggestions]="fundSuggestions"
(completeMethod)="filterValues($event)"
field="value"
delay="500"
[dropdown]="false"
[multiple]="false">
</p-autoComplete>
但是,我不能这样做。我的 AutoComplete 控件实际上是在 *ngFor
循环中动态创建的,我的屏幕上可能有几个这样的控件。
我发现 filterValues()
函数 did 启动,它did 加载值列表并将其绑定到 fnd.fundSuggestions
数组,但控件没有显示任何建议。
解决方案是这样的...与其将 [suggestions]
设置为直接指向 fnd.fundSuggestions
数组,我需要将其指向一个 observable。
因此,在我的 filterValues() 函数中,我将使用 of()
创建一个可观察对象:
filterValues(event, fnd) {
fnd.fundSuggestions = [];
let searchString = (event.query ?? '').toLowerCase();
if (searchString.length < 3) {
return;
}
let body = JSON.stringify(searchString);
let URL = 'https:\\someservice.com\searchForFunds";
this.mikesService.searchService(URL, body).subscribe(
data => {
fnd.fundSuggestions = data;
fnd.observable = of(fnd.fundSuggestions);
}
);
}
我改变了我的控制来从这里得到这个建议:
<div *ngFor="let fnd of listOfFunds">
<p-autoComplete
[(ngModel)]="fnd.chosenFund"
[suggestions]="fnd.observable | async"
(completeMethod)="filterValues($event, fnd)"
field="value"
delay="500"
[dropdown]="false"
[multiple]="false">
</p-autoComplete>
</div>
这个问题花了我很长时间才解决...我希望这对其他开发者有用。
答案 4 :(得分:0)
谢谢@ Mike Gledhill -> 应该接受谁的回答......顺便说一句
只是想将此添加为单个实例
使用
$filtered = new BehaviorSubject([]);
this.$filtered.next([...items]);//此位为BehaviorSubject Observable分配新的引用
getItems($event) {
this._itemsServiceProxy
.getItems($event.query)
.subscribe((items: ItemDto[]) => {
this.$filtered.next([...items]);
});
}
我就是这样消费的:
[建议]="$filtered | async"
[showEmptyMessage]="($filtered | async).length === 0"
(completeMethod)="getItems($event)"
<p-autoComplete name="items" [(ngModel)]="selectedItem"
[field]="selectedItemDisplayConverter" [dropdown]="true" forceSelection="true" dataKey="id"
[placeholder]="l('SearchItemThreeDots')"
[suggestions]="$filtered | async"
[showEmptyMessage]="($filtered | async).length === 0"
(completeMethod)="getItems($event)"
[emptyMessage]="l('NoItemsFound')" required [delay]="750">
<ng-template let-item pTemplate="item">
<div class="row">
<div class="col-md-12">
{{ item.clientName }}<br />
<a href="javascript:;"><small>{{ item.name }}</small></a>
</div>
</div>
</ng-template>
</p-autoComplete>
对于我使用此方法正确显示所选项目的字段
selectedItemDisplayConverter(selectedItem: ItemDto) {
return selectedItem.clientName + ': ' + selectedItem.name;
}