我正在使用Angular6以及ng-bootstrap
的{{3}}
场景
手风琴的每个部分有两种不同的形式。当手风琴的一部分打开时,另一部分关闭,而另一部分中的窗体关闭,它也将重置。一种形式是“键入时搜索”,因此它使用了pipe
和async pipe
。另一种形式是带有下拉菜单的简单“提交帖子”。
我的代码
HTML
<ngb-accordion (panelChange)="beforeChange($event)" [closeOthers]="true" activeIds="cpNameSection">
<ngb-panel id="cpNameSection" title="name">
<ng-template ngbPanelContent>
<form [formGroup]="cpSearchForm">
<label>
<input type="text" formControlName="cpName" >
</label>
<label>
<select name="cp" selected formControlName="cpDrop">
<option value="construction" >construction</option>
<option value="place">place</option>
</select>
</label>
</form>
<div *ngIf='cpSearchFormLoading'>loading results</div>
<div *ngIf='cpSearchForm.controls.cpName.value.length>0 && results | async ; let items' id="cpNameResults">
<div *ngFor='let item of items'><button type="button" (click)="getPointById(item.id,cpDropValue)" name="button">{{item.name}}</button></div>
<div *ngIf='cpSearchForm.dirty && items.length === 0 && cpSearchForm.controls.cpName.value !== "" '>
This dooes not exist. Want to insert it?
<button type='button' (click)="insertNewCp(cpSearchForm.controls.cpName.value, cpDropValue)">insert {{cpSearchForm.controls.cpName.value}}</button>
</div>
</div>
</ng-template>
</ngb-panel>
<ngb-panel id="cpCategoriesSection" title="categories">
<ng-template ngbPanelContent>
<form [formGroup]="constructionSearchForm" (ngSubmit)="searchConstruction()">
<label>era
<select name="era" selected formControlName="era">
<option value="" > === </option>
<option *ngFor='let item of era' value="{{item.id}}" >{{item.name}}</option>
</select>
</label>
<hr>
<label>type
<select name="type" selected formControlName="type">
<option value="" > === </option>
<option *ngFor='let item of type' value="{{item.id}}" >{{item.name}}</option>
</select>
</label>
<button type="submit">Submit</button>
</form>
</ng-template>
</ngb-panel>
</ngb-accordion>
打字稿
cpDropValue:String;
this.results = this.cpSearchForm.valueChanges.pipe(
debounceTime(400),
distinctUntilChanged(),
filter(formdata => formdata.cpName.length > 0),
tap( () => this.cpSearchFormLoading = true),
switchMap( formdata => this.flipService.getByName(formdata.cpName, formdata.cpDrop)),
shareReplay(1),
tap( () => this.cpSearchFormLoading = false),
tap( () => this.cpDropValue = this.cpSearchForm.controls.cpDrop.value)
);//pipe
public beforeChange($event: NgbPanelChangeEvent) {
if ($event.panelId === 'cpNameSection' && $event.nextState === true) {
this.constructionSearchForm.reset({
era:'',
type:''
});
}
if ($event.panelId === 'cpCategoriesSection' && $event.nextState === true) {
this.cpSearchForm.reset({
cpName: '',
cpDrop: this.cpDropValue
});
}
}
当cpSearchForm
的任何值发生变化(类型或下拉列表)时,开始搜索。除非文本字段中没有任何值。如果有一个值并且有一些结果,则开始显示结果。如果没有结果返回且文本字段中有值,则插入。
问题
当页面首次加载并且我在cpSearchForm
中键入要搜索的第一个字母时,pipe
无效,即使tetxfield中有一个值,它也会触发。没有呼叫后端。我必须添加第二个字母才能使代码正常工作。之后,它工作正常。我可以删除所有内容并键入一个字母,它将起作用。但是在页面加载后的第一次,一个字母不会触发代码。这是我要解决的问题,我不知道如何进行。
我尝试过的事情
从cpSearchForm.controls.cpName.value.length>0 &&
部分的cpSearchForm
的检查部分删除results | async
部分,可以解决此问题。
但是,打开constructionSearchForm
表单的手风琴部分,将其关闭,打开cpSearchForm
表单的手风琴部分,结果部分永远不会清除。表单被重置,但是您之前搜索的结果仍然存在。
因此,手风琴单击实际上是有效的,因为它重置了表单,cpSearchForm
被重置,但是由于缺少用于空白文本字段的cpSearchForm.controls.cpName.value.length>0
检查,因此以前的结果仍然存在。但是以某种方式相同的检查不允许管道代码立即触发(?)
我还尝试了cpSearchForm.controls.cpName.value != ""
进行检查,仍然是同样的问题。 cpSearchForm.controls.cpName.value != ""
和cpSearchForm.controls.cpName.value.length>0
实际上都可以工作。
谢谢