有一个FormGroup,其中填充了FormArray和相对的FormControl。 我构建了一个服务(valuechange Observable),它使用给定的字符串查找"字典中的相似单词"阵列。该服务返回一个对象数组,该数组应填充输入下的建议列表。
建议清单由与此类似的3个术语组成。
我给表'表'字符串并返回:
[
{distance: 1, match : 'Table'},
{distance: 3, match : 'Fabules'},
{distance: 5, match : 'Ramioles'},
]
使用Levenstein算法计算距离,并指示必须执行多少次更改才能获得给定的单词。
现在我需要构建动作。我点击该术语,值更改,列表消失。
重要的是,对于填充的每个输入,服务都以(焦点)开头,并返回其建议列表。
component.html
<form [formGroup]="myForm">
<fieldset formArrayName="parameters">
<ng-container *ngFor="let par of parameters.controls" [formGroup]="par">
<input formControlName="name" />
<ul class="filter-select">
<li *ngFor="let r of results" class="filter-select-list">
{{ r.match }}
</li>
</ul>
</ng-container>
</fieldset>
</form>
我不想使用像ng2-completer或材料自动完成这样的库,最重要的是我不能使用datalist,因为如果给定的字符串是&#34; tablered&#34;并且在字典中出现了单词&#34; Table Red&#34;,数据列表没有出现。
第二个datalist只是HTML5,只有交叉浏览问题。
我该如何实现这种行为?
回顾:
component.html
<input [formControl]="queryField" type="text" />
service.ts
this.queryField.valueChanges
.debounceTime(200)
.distinctUntilChanged()
.subscribe( value => {
this.results = this._searchService.spell(value)
})
第二部分
我想出了类似下面的内容。 使用输入焦点上的Observable,将填充列表。
@Component({
selector: 'my-autocomplete-input',
styleUrls: ['./app.component.css'],
template: `
<ng-content></ng-content>
<ul class="filter-select">
<li *ngFor="let r of autosuggestList" class="filter-select-list">
<div (click)="editInput(r.match)">{{ r.match }}</div>
</li>
</ul>
`
})
export class AutocompleteComponent {
@ContentChild("input") input: ElementRef;
@Input() autosuggestList;
constructor(
private _searchService: SearchService,
) {}
editInput(res) {
this.input.nativeElement.value = res;
this.autosuggestList = [];
}
ngAfterViewInit() {
Observable.fromEvent(this.input.nativeElement, 'focus')
.subscribe((data: KeyboardEvent) => {
this.autosuggestList = this._searchService.spell(this.input.nativeElement.value)
});
}
}
但是表单数组没有更新我必须在输入上按一下才能更改FormControl中的值&#34; name&#34;。
如何从contentChild修补/更新表单?在editInput函数中更精确?
答案 0 :(得分:0)
我不明白为什么你有两个输入:名称和值...我假设一个,输入的东西就足够了,然后你得到一个下拉菜单来选择一些东西并填入输入。否?
创建一个AutocompleteInputComponent,以便将代码放在一个很好的专用位置。在那里你放置一个始终属于<input>
类型的那个(在那个组件中你声明@ContentChild('input') input: ElementRef;
)
现在你可以在你父母的组件中说:
<ng-container *ngFor="let par of parameters.controls" [formGroup]="par">
<my-autocomplete-input [autosuggestList]="valuechange">
<input formControlName="name"/>
</my-autocomplete-input>
</ng-container>
如果您还需要第二个输入,您可以使用css选择器在contentchildren之间进行区分:https://scotch.io/tutorials/angular-2-transclusion-using-ng-content