【问题标题】:BB Marionette: best way to update a collection without re-renderingBB Marionette:无需重新渲染即可更新集合的最佳方式
【发布时间】:2013-09-02 20:17:59
【问题描述】:

我有一个非常简单的页面,在表格中显示了一个集合。在其上方有一个搜索字段,用户可以在其中输入用户的名字。

当用户键入时我想过滤列表。

编辑:我更新了代码以显示当前的复合视图是如何工作的。我的目标是集成一个可以 _.filter 集合并希望只更新集合表的 searchView。

define([
  'marionette',
  'text!app/views/templates/user/list.html',
  'app/collections/users',
  'app/views/user/row'
],
  function (Marionette, Template, Users, User) {
    "use strict"

    return Backbone.Marionette.CompositeView.extend({
      template: Template,
      itemView: User,
      itemViewContainer: "tbody",
      initialize: function() {
        this.collection = new Users()
        this.collection.fetch()
      }
    })
  })

【问题讨论】:

  • 为什么不从模板中移出#search-users-entry,这样它就不会被重新渲染?
  • 中肯的建议,谢谢

标签: backbone.js marionette


【解决方案1】:

将您的模板分成几个小模板,这样可以提高客户端的性能,您不会遇到覆盖表单元素的问题,并且您有更多可重用的代码。

但是要注意太多的分离,因为更多的模板意味着更多的视图和更多的代码/逻辑。

【讨论】:

  • 所以我要在 searchUsersView 上添加一个监听器?
  • 是的,将 searchUsersView 创建为 usersView 的子项,并将事件方法传递给 searchUsersView,该方法在表单更改时触发。
  • 你会推荐一个可重复使用的 searchView 吗?
  • 是的,在我自己的(仅限骨干网)应用程序中,我遇到了同样的问题,并使用子搜索视图解决了它。
【解决方案2】:

您似乎没有充分利用CollectionView。如果我是你,我会将搜索框和搜索结果之间的关注点分开。将它们作为单独的视图,这样当一个需要重新渲染时,它不会影响另一个。

此代码可能无法立即运行,因为我尚未对其进行测试。但希望它能给您一些线索,了解 ItemViewCollectionViewLayout 是什么以及它们如何帮助您删除一些样板代码

//one of these will be rendered out for each search result.
var SearchResult = Backbone.Marionette.ItemView.extend({
    template: "#someTemplateRepresentingEachSearchResult"
)};

//This collectionview will render out a SearchResult for every model in it's collection
var SearchResultsView = Backbone.Marionette.CollectionView.extend{
    itemView: SearchResult
});

//This layout will set everything up
var SearchWindow = Backbone.Marionette.Layout.extend({
    template: "#someTemplateWithASearchBoxAndEmptyResultsRegionContainer",
    regions:{
        resultsRegion: "#resultsRegion"
    },
    initialize: function(){
        this.foundUsers = new Users();
        this.allUsers = new Users();
        this.allUsers.fetch({
            //snip...
        });
    events: {
        'keyup #search-users-entry': 'onSearchUsers'
    },
    onSearchUsers: function(e){
        var searchTerm = ($(e.currentTarget).val()).toLowerCase()

        var results = this.allUsers.filter(function(user){
            var firstName = user.attributes.firstname.toLowerCase();
            return firstName.match(new RegExp(searchTerm))
        });

        this.foundUsers.set(results); //the collectionview will update with the collection
    },
    onRender: function(){
        this.resultsRegion.show(new SearchResultsView({
            collection: this.foundUsers
        });
    }
});

我认为您需要注意的最重要的事情是CollectionView 如何利用您提供的Backbone.CollectionCollectionView 将为它的集合中的每个模型呈现一个 itemView(你给它的类/类型)。如果Collection 发生变化,那么CollectionView 也会发生变化。您会注意到在方法onSearchUsers 中您需要做的就是更新该集合(使用set)。 CollectionView 将监听该集合并相应地更新自己

【讨论】:

  • 我不同意为此使用布局。我已经有一个具有侧边栏/全局搜索/内容区域的页面布局布局。我的印象是,compositeView 将允许我拉入许多视图并允许集合重新激活
  • 您说得非常正确,layout 是不必要的。我只是使用一个布局来演示我认为最适合您想要的模式。我认为搜索项的过滤和搜索栏本身应该与结果的实际显示不同。这就是我试图在我的布局中展示的内容。我创建了一个collection 的用户,并将其传递给SearchResultView。然后从其他地方(也知道搜索词)更新该集合,该集合将是反应性的并相应地更新
猜你喜欢
  • 2013-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多