【问题标题】:Dart Polymer: How to filter elements in repeat-template?Dart Polymer:如何过滤重复模板中的元素?
【发布时间】:2014-02-18 04:36:00
【问题描述】:

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

my-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> 

my-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());
  }
} 

例如,当我在文本框中键入“Mo”时,我希望项目列表会自动更新,从而只显示“Monday”。但是,在键入任何搜索词时,列表保持不变并且搜索词被忽略。

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

【问题讨论】:

  • 什么不起作用?您是否验证了searchTerm 是否被设置以及matchesSearchFilter 是否被调用?
  • 是的,searchTerm 设置正确。 matchesSearchFilters 在第一次呈现列表时被调用(但不是在 searchTerm 发生变化时)。
  • 你可以试试stackoverflow.com/questions/20004117这里我发布了另一个过滤器示例,如果你想尝试这条路线stackoverflow.com/questions/20323815可能会有所帮助

标签: dart dart-polymer


【解决方案1】:

第二种选择是添加一个过滤器:

  <template repeat="{{ item in items | filter(searchTerm)}}">
      <li>{{ item }}</li>
  </template>

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

项目在用于重复循环之前将被过滤。 我个人更喜欢使用过滤器而不是 Günter 的解决方案,因为:
- 这很容易
- 集中
- 使用管道运算符添加其他过滤器是可以理解的
- 您的列表没有改变(仅过滤)

例如,假设您还想对商品进行分类。然后只需添加另一个过滤器:

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

您的项目将被过滤然后排序(每次 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>

然后在你的课堂上

@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);
  }
} 

【讨论】:

  • 好文章!我也喜欢过滤器,但在这种情况下没有想到它们。我只将它们用于转换。
  • 我认为我们可以在任何地方使用过滤器 /transformer。我为我们的 Dart Flight School 编写了一个 2 小时的代码实验室,并使用该技术对电影进行过滤和排序。 GitHub repo:github.com/eric-taix/movie-board,还有一个应用程序的在线演示:eric-taix.github.io/movie-board
  • 是的,好东西,埃里克!但实际上,过滤线必须是filter(term) =&gt; (List&lt;String&gt; entries) =&gt; term.isEmpty [...],对吧?否则,列表不会显示。
【解决方案2】:

另一种解决方案是创建一个包含所有项目的列表allItems,并且当searchTerm 更改时更新items 之类的:

  @observable List<String> items = ['Monday', 'Tuesday', 'Wdnesday'];

  void searchTermChanged(oldVal) {
    items = items.where((String item) {
      if (searchTerm.isEmpty) return true;
      return item.toLowerCase().contains(searchTerm.toLowerCase());      
    }).toList(growable: false);
  }

在这种情况下,您不需要toObservable,因为观察是否添加或删除项目是多余的。要观察items 列表是否被替换,@observable 属性应该足够了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    相关资源
    最近更新 更多