【问题标题】:Angular 2 Material - Using MD's autocomplete example in a formAngular 2 Material - 在表单中使用 MD 的自动完成示例
【发布时间】:2018-08-28 19:21:32
【问题描述】:

有没有办法让自动完成功能在表单中工作?我有一个输入地址的表格。我正在对州(这是在美国)使用自动完成(copied from Material Design's docs),并且除了所选状态未设置为 user.state 之外,它正在工作。因此,当我在提交时控制台注销 myForm.form.value 时,它​​看起来像这样:

user.name : "Test"
user.phone: ...
etc.

user.state 甚至没有出现。

我的(相关)代码:

<md-input-container>
  <input 
    mdInput 
    placeholder="State" 
    [mdAutocomplete]="auto"
    [formControl]="stateCtrl"
    name="user.state" 
    [(ngModel)]="user.state"
  >
</md-input-container>

<md-autocomplete 
    #auto="mdAutocomplete"
>
  <md-option 
    *ngFor="let state of filteredStates | async" [value]="state"
    (onSelectionChange)="selectState(state)"
  >
    {{ state }}
  </md-option>
</md-autocomplete> 

TS:

  constructor(public dialog: MdDialog,) { 
    this.stateCtrl = new FormControl();
    this.filteredStates = this.stateCtrl.valueChanges
        .startWith(null)
        .map(name => this.filterStates(name));
  }

  filterStates(val: string) {
    return val ? this.states.filter(s => new RegExp(`^${val}`, 'gi').test(s))
               : this.states;
  }

即使我尝试使用 (onSelectionChange) 调用函数 selectState(state) 来设置 user.state,当我在提交时 console.log 表单时它仍然不显示。

  selectState(value){
    this.user.state = value;
  }

【问题讨论】:

  • 这里有点困惑——首先,你为什么在值的输入上同时执行 ngModel 和 formControl ?如果您删除了 ngModel 并在 formControl 上执行了 valueChanges,它会显示该值吗?您是否有一个 formGroup 作为表单控件的父级?自动完成应该与不改变的值无关,所以有些东西被错误地实现了。

标签: angular typescript autocomplete angular-material2


【解决方案1】:

看看这个 GitHub 示例:Demo with md-autocomplete (forms)

有一个响应式表单和模板驱动表单的示例。使用模板驱动的表单,您可以完全删除formControl,而只需使用[(ngModel)](ngModelChange)。以下是模板驱动解决方案的示例:

<form #f="ngForm">
  <md-input-container>
    <input mdInput placeholder="State" [mdAutocomplete]="tdAuto" name="state" 
       #state="ngModel" [(ngModel)]="currentState"
      (ngModelChange)="tdStates = filterStates(currentState)">
  </md-input-container>

  <md-autocomplete #tdAuto="mdAutocomplete">
    <md-option *ngFor="let state of tdStates" [value]="state">
      <span>{{ state }}</span>
    </md-option>
  </md-autocomplete>    
</form>

在组件中,我们将过滤后的值分配给不同的变量 (tdStates),并将所有状态保存在 states 数组中:

filterStates(val: string) {
  if (val) {
    const filterValue = val.toLowerCase();
    return this.states.filter(state => state.toLowerCase().startsWith(filterValue));
  }
  return this.states;
}

DEMO

【讨论】:

  • 如何在动态行中实现相同的例子:如果我们点击加号按钮,新行将出现在自动完成应该工作的地方。 ?有什么想法吗?
  • 演示链接是404
  • 经过一番摆弄,我设法让它与 mat-input 和 mat-autocomplete 一起工作,原理是一样的。我必须添加的是输入(焦点)方法中 this.states 的“刷新”,因为我有多个输入应该使用相同的变量
【解决方案2】:

我从材料的网站上拿了form 的例子并添加了md-autocomplete 到它。在演示中,您可以从自动完成中筛选和选择一个状态。提交表单后,您可以看到传递给 alert 的值。

HTML:

plunker 中的完整代码demo

<form>

// add all form code

<md-autocomplete #auto="mdAutocomplete" >
    <md-option *ngFor="let state of filteredStates | async" [value]="state" (onSelectionChange)="selectState(state, addForm.value)">
      {{ state }}
    </md-option>
</md-autocomplete>

</form>

app.ts:

selectState(state, form){
    form.state = state;
  }

【讨论】:

    【解决方案3】:
      states = [];
      tdStates = [];
      currentState = '';
    
      ngOnInit() {
        this.states= [
          {code: 'AL', name: 'Alabama'},
          {code: 'AK', name: 'Alaska'},
          {code: 'AZ', name: 'Arizona'},
          {code: 'AR', name: 'Arkansas'},
          {code: 'CA', name: 'California'},
          {code: 'CO', name: 'Colorado'},
          {code: 'CT', name: 'Connecticut'},
          {code: 'DE', name: 'Delaware'},
          {code: 'FL', name: 'Florida'},
          {code: 'GA', name: 'Georgia'},
          {code: 'HI', name: 'Hawaii'},
          {code: 'ID', name: 'Idaho'},
          {code: 'IL', name: 'Illinois'},
          {code: 'IN', name: 'Indiana'},
          {code: 'IA', name: 'Iowa'},
          {code: 'KS', name: 'Kansas'},
          {code: 'KY', name: 'Kentucky'},
          {code: 'LA', name: 'Louisiana'},
          {code: 'ME', name: 'Maine'},
          {code: 'MD', name: 'Maryland'},
          {code: 'MA', name: 'Massachusetts'},
          {code: 'MI', name: 'Michigan'},
          {code: 'MN', name: 'Minnesota'},
          {code: 'MS', name: 'Mississippi'},
          {code: 'MO', name: 'Missouri'},
          {code: 'MT', name: 'Montana'},
          {code: 'NE', name: 'Nebraska'},
          {code: 'NV', name: 'Nevada'},
          {code: 'NH', name: 'New Hampshire'},
          {code: 'NJ', name: 'New Jersey'},
          {code: 'NM', name: 'New Mexico'},
          {code: 'NY', name: 'New York'},
          {code: 'NC', name: 'North Carolina'},
          {code: 'ND', name: 'North Dakota'},
          {code: 'OH', name: 'Ohio'},
          {code: 'OK', name: 'Oklahoma'},
          {code: 'OR', name: 'Oregon'},
          {code: 'PA', name: 'Pennsylvania'},
          {code: 'RI', name: 'Rhode Island'},
          {code: 'SC', name: 'South Carolina'},
          {code: 'SD', name: 'South Dakota'},
          {code: 'TN', name: 'Tennessee'},
          {code: 'TX', name: 'Texas'},
          {code: 'UT', name: 'Utah'},
          {code: 'VT', name: 'Vermont'},
          {code: 'VA', name: 'Virginia'},
          {code: 'WA', name: 'Washington'},
          {code: 'WV', name: 'West Virginia'},
          {code: 'WI', name: 'Wisconsin'},
          {code: 'WY', name: 'Wyoming'},
        ];
      }
    
      filterStates(val: string) {
        if (val) {
          const filterValue = val.toLowerCase();
          return this.states.filter(state => state.name.toLowerCase().startsWith(filterValue));
        }
        return this.states;
      }
    

    【讨论】:

      【解决方案4】:
        <md-input-container>
          <input mdInput placeholder="State" [mdAutocomplete]="tdAuto" name="state" 
             #state="ngModel" [(ngModel)]="currentState"
            (ngModelChange)="tdStates = filterStates(currentState)">
        </md-input-container>
      
        <md-autocomplete #tdAuto="mdAutocomplete">
          <md-option *ngFor="let state of tdStates" [value]="state.name">
            <span>{{ state.name }}</span>
          </md-option>
        </md-autocomplete>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-13
        • 1970-01-01
        • 2018-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-30
        相关资源
        最近更新 更多