Angular 5的建议清单

时间:2018-04-29 14:55:48

标签: angular forms typescript autosuggest

有一个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,只有交叉浏览问题。

我该如何实现这种行为?

回顾:

  1. 此数组的每个输入必须挂钩到一个服务ON FOCUS,它在字典中查找单词(仅使用一个输入 - 看下面 - 但不是在* ngFor中)
  2. 此服务返回一个数组并填充建议列表(已完成)
  3. 然后点击建议
  4. 价值变动
  5. 列表消失
  6. 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函数中更精确?

1 个答案:

答案 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