角度材质中的自由文本输入mdAutoComplete

时间:2016-06-14 23:41:36

标签: angular-material md-autocomplete

我希望我的角度素材自动填充是一个建议列表,但不是要求。但是我不确定如何实现,因为它们不是Angular Material文档中的明确例子。

在下面的示例中,我的模型是$ctrl.item.category

显然,下面的示例是错误的,因为我的模型已链接到md-selected-item,但这仅在我选择项目时才有效。我希望用户能够在项目不在列表中时自由输入文本。基本上,自动完成在大多数浏览器中是如何工作的。

我看到很多关于如何禁用此功能的问题,但是当没有选择项目时,他们并没有尝试禁用清除左侧文本。在这些情况下,如果未选择项目,则模型值为null,但文本将保留在输入中。

如果此人没有选择(或未进行匹配),我希望输入的文本是模型值。

md-autocomplete(
  md-floating-label="Category Name"
  flex="50"
  md-input-name="category"
  md-selected-item="$ctrl.item.category"
  md-search-text="catSearch"
  md-items="category in $ctrl.categories"
  md-item-text="category"
  md-min-length="0"
  md-select-on-match=""
  md-match-case-insensitive=""
  required=""
  )
  md-item-template
    span(md-highlight-text="catSearch" md-highlight-flags="^i") {{category}}

我的选项($ctrl.categories)是一个字符串数组['Food','Liqour'],我希望用户能够使用其中一个或免费输入Tables作为他们的选择。

2 个答案:

答案 0 :(得分:2)

在这种情况下,您应该将 md-search-text 链接到您的模型。

如果要实施模糊搜索,则必须自己编写过滤方法。看看这个例子:

模板:

  <md-autocomplete
    md-items="item in $ctrl.itemsFilter()"
    md-item-text="item.label"
    md-search-text="$ctrl.query"
    md-selected-item="$ctrl.selected"
    >
    <md-item-template>
      <span md-highlight-text="$ctrl.query">{{item.label}}</span>
    </md-item-template>

     <md-not-found>
        No item matching "{{$ctrl.query}}" were found.
     </md-not-found>        

   <div ng-messages="$ctrl.myValidator($ctrl.query)">
      <div ng-message="short">Min 2 characters</div>
      <div ng-message="required">Required value</div>
    </div>

  </md-autocomplete>

控制器:

var items = [ ... ];
ctrl.itemsFilter = function itemsFilter() {
    return ctrl.query ? filterMyItems(ctrl.query) : items;
};
ctrl.myValidator = function (value) {
  return {
    short: value && value.length < 2,
    required : value && value.length < 1,
  };
};

然后你只需要添加filterMyItems方法来过滤你的项目

答案 1 :(得分:2)

为了改进@masitko的答案,我已经以某种方式实现了过滤器,它将查询添加到过滤后的列表中。因此它变得可选并且是有效选项。因此,可以自动填充建议框。

我在我的项目中使用ES6。但它应该很容易适应ES5代码。

myFilter() {
    if (!this.query) return this.items;

    const
        query = this.query.toLowerCase(),
        // filter items where the query is a substing
        filtered = this.items.filter(item => {
            if (!item) return false;
            return item.toLowerCase().includes(query);
        });

    // add search query to filtered list, to make it selectable 
    // (only if no exact match).
    if (filtered.length !== 1 || filtered[0].toLowerCase() !== query) {
        filtered.push(this.query);
    }

    return filtered;
}