Angular不更新datalist DOM元素

时间:2017-04-19 05:51:57

标签: angular

我有这个输入字段:

<input type="text" list="myList">
<datalist id="myList">
  <option *ngFor="let loc of locationList">{{ loc.description }}</option>
</datalist>

这是一件非常简单的事情。 datalist提供自动填充选项,并由数组填充。该阵列由服务更新。

这就是问题所在。无论服务升级阵列 - 它都可以在控制台上进行检查,它实际上正在更新 - datalist的内容在另一个按键之前不会改变。

在Chrome中,我发现ChangeDetectorRef.detectChanges()消除了这个问题。但在Firefox下它仍然存在。 Firefox仅在用户按Backspace时更新datalist。如果他只是一直打字,那就没有了。

有没有办法告诉Angular刷新绑定到这个数组的所有绑定?

4 个答案:

答案 0 :(得分:0)

我猜您的服务会同步更新locationList(不是因为XHR或超时)。它是由Angular的变更检测和刷新策略和区域(zone.js)引起的。请查看以下文章,了解更多信息非常重要:

答案 1 :(得分:0)

这里使用的是HTML 5,而不是Angular。您依赖于浏览器实现。 我建议你使用旧时尚方法:

<div class="container" >
    <div class="input-field col s12">
      <input type="text" class="validate filter-input" [(ngModel)]=query (keyup)=filter()>
    </div>
    <div class="suggestions" *ngIf="locationList.length > 0">
        <ul *ngFor="let loc of locationList" >
            <li >
                <a (click)="select(loc)">{{loc.description}}</a>
            </li>
        </ul>
    </div>
</div>  

使用以下方法更新您的组件:

query: string;
locationList: [];

filter() {
    if (this.query !== ""){
        this.locationList = this.service.getLocations().filter(function(el){
            return el.toLowerCase().indexOf(this.query.toLowerCase()) > -1;
        }.bind(this));
    }else{
        this.locationList = [];
    }
}

select(item){
    this.query = item;
    this.locationList = [];
}

这是一个更详细的工作示例:http://4dev.tech/2016/03/tutorial-creating-an-angular2-autocomplete/

答案 2 :(得分:0)

如果你在Angular之外调用Javascript,你必须使用NgZone(基于ZoneJS框架)来更新你的Angular模型。

例如:

import {Component, NgZone} from '@angular/core';

@Component({
  ...
})
export class YourComponent { {

  locationList: any[];
  constructor(private ngZone: NgZone) {}

  updateDataList() {
    googleMapsToPromise().then(locations => {
         this.locationList = location;
         this.ngZone.run(() => {
           console.log('model updated') 
         });
      }
    }
  }

}

此处的文档:https://angular.io/docs/ts/latest/api/core/index/NgZone-class.html

这是googleMapsToPromise实施的一个示例:https://jamesbedont.com/2016/03/23/GoogleMapsApiIntroduction.html#geocode

答案 3 :(得分:0)

好的。在这里没有任何修补区域的帮助。我花了差不多两天的时间试图让它工作,然后我把它扔掉了,并在十分钟内用datalist替换了它。

<input type="text" class="form-control" formControlName="location" [(ngModel)]="currentLocation">

<div class="panel panel-default panel-body datalist" *ngIf="locationList.length > 0 && !(locationList.length == 1 && locationList[0].description == currentLocation)">
    <ul>
        <li *ngFor="let loc of locationList"><a (click)="changeLocation(loc.description)">{{ loc.description }}</a></li>
    </ul>
</div>

这是一个Bootstrap面板,每当有可供选择的东西时出现。它适用于每个浏览器,没有更新问题。另外,我可以检测用户是否从列表中选择了一个选项,因此我得到了有效的响应。添加一个加载器微调器也很容易(我实际上做了,但我保持这个片段简单。)

今天的经验教训:不要尝试在Angular中使用datalist。只是不要。