Dart Polymer:如何过滤repeat-template中的元素?

mel*_*mac 7 dart dart-polymer

我正在使用Dart Polymer的重复模板来显示列表项.现在,我想实现一个搜索过滤器,其中只显示与输入的搜索词相关的项目.请考虑以下代码:

我-element.html

<polymer-element name="my-element">
  <script type="application/dart" src="my-element.dart"></script>
  <template>
    <input type="text" value="{{ searchTerm }}">
    <ul>
      <template repeat="{{ item in items }}">
        <template if="{{ matchesSearchFilter(item) }}">
          <li>{{ item }}</li>
        </template>
      </template>
    </ul>
  </template>
</polymer-element> 
Run Code Online (Sandbox Code Playgroud)

我-element.dart

@CustomTag('my-element')
class MyElement extends PolymerElement {
  @observable List<String> items = toObservable(["Monday", "Tuesday", "Wednesday"]);
  @observable String searchTerm = '';

  MyElement.created() : super.created();

  matchesSearchFilter(String item) {
    if (searchTerm.isEmpty) return true;
    return item.toLowerCase().contains(searchTerm.toLowerCase());
  }
} 
Run Code Online (Sandbox Code Playgroud)

例如,当我在文本框中键入"Mo"时,我希望项目列表会自动更新,这样只显示"星期一".但是,在键入任何搜索词时,列表保持不变,并忽略搜索词.

那么,如何正确实现这样的功能呢?

Eri*_*aix 13

第二种方法是添加过滤器:

  <template repeat="{{ item in items | filter(searchTerm)}}">
      <li>{{ item }}</li>
  </template>
Run Code Online (Sandbox Code Playgroud)

// One line
filter(term) => (items) => term.isEmpty ? items : items.where((item) => item.toLowerCase().contains(searchTerm.toLowerCase())).toList();
Run Code Online (Sandbox Code Playgroud)

在重复循环中使用之前,项目将被过滤.我个人更喜欢使用过滤器而不是Günter的解决方案,因为:
- 它很容易
- 集中
- 用管道操作员添加其他过滤器是完全可以理解的
- 你的列表没有改变(只有过滤)

例如,假设您还想对项目进行排序.然后添加另一个过滤器:

<template repeat="{{ item in items | filter(searchTerm) | sort(sortField, sortAsc)}}">
      <li>{{ item }}</li>
</template>
Run Code Online (Sandbox Code Playgroud)

您的项目将被过滤然后排序(每次searchTerm,sortField或sortAsc更改).简单 ;-)

最后一个提示:前面的代码会在每次击键时过滤你的列表,这对用户不是很友好!

相反,您可以使用这种代码:

// Note that now I filter items on searchFilter and not more on searchTerm
<template repeat="{{ item in items | filter(searchFilter) | sort(sortField, sortAsc)}}">
      <li>{{ item }}</li>
</template>
Run Code Online (Sandbox Code Playgroud)

然后在你的课堂上

@CustomTag('my-element')
class MyElement extends PolymerElement {

  @observable List<String> items = toObservable(["Monday", "Tuesday", "Wednesday"]);
  @observable String searchTerm = '';
  @observable String searchFilter = '';

  MyElement.created() : super.created();

  filter(term) => (items) => term.isEmpty ? items : items.where((item) => item.toLowerCase().contains(searchTerm.toLowerCase())).toList();

  // When the user keystroke, searchTerm is changed
  // Launch a Timer (if the timer was not null then stop it: it means the user has not finished
  // When the delay is elapsed then set searchFilter with searchTerm
  // As your filter use 'filter(searchFilter)' then your items will be filtered
  Timer _searchTimer;
  searchTermChanged(oldValue) {
    // If there's another keystroke during the delay then reset it
    if (_searchTimer != null) _searchTimer.cancel();
    new Timer(new Duration(milliSeconds: 300), () => searchFilter = searchTerm);
  }
} 
Run Code Online (Sandbox Code Playgroud)