Backbone Marionette CompositeView sorted list - renders extra model on add

此生再无相见时 提交于 2020-01-04 09:13:22

问题


Here's the fiddle:

http://jsfiddle.net/QhQ8D/10/

Code is down below. Making a chat app and need a sorted, connected user list. Figured Collection with a comparator on name hooked to a CompositeView should do it. Am I doing something wrong in the implementation here?

HTML:

    <div>Enter user name and hit add user to build your list</div>
    <div id="divadduser">
        <input id="inputusername"/>
        <input id="buttonadduser" type="button" value="add user"/>
    </div>

    <div id="divusers"></div>

JAVASCRIPT:

    var nextAvailableUserId = 0;

    //Define a region to show a list of users 
    var userListRegion = new Backbone.Marionette.Region({ el: '#divusers'});

    var ConnectedUserModel = Backbone.Model.extend();

    //Make a user item view
    var UserView = Backbone.Marionette.ItemView.extend({
        template: Handlebars.compile(
            '<a id="{{id}}">{{name}}</a>'        
        ),
        tagName: "li",   
    });

    //Define a user collection
    var UserCollection = Backbone.Collection.extend({
        model: ConnectedUserModel,
        comparator: "name"
    });

    //Make a user collection instance
    var collConUsers = new UserCollection();                   

    //Define a composite user list view 
    var UserListView = Backbone.Marionette.CompositeView.extend({
        template: Handlebars.compile(
           '<ul id="ulusers"></ul>'
        ),

        itemView: UserView,
        itemViewContainer: 'ul',

        collectionEvents: {
            "add": "doSort"
        },

        doSort: function () {
            this.collection.trigger('reset');
        }
    });

    //Make a composite user list view instance
    var view = new UserListView({
        collection: collConUsers                        
    });

    //Show the view
    userListRegion.show(view);

    //Handle add user button click
    $('#buttonadduser').click(function () {    
        var uName = $("#inputusername").val();
        if (uName.length > 0) {
            nextAvailableUserId += 1;
            collConUsers.add([{ id: nextAvailableUserId, name: uName }]);        
            $("#inputusername").val('');
        }
    });

UPDATE:

I'm leaving this marked answered but the solution below is not optimal. In essence it overrides how CollectionView or CompositeView appendHtml. Technically this helps the issue described in this thread but it seems to create other problems. In my case I also have a JQuery filter on my user list (like this - http://kilianvalkhof.com/uploads/listfilter/). This override breaks that filter. Not sure why just yet. If I discover why I'll update this post.

After a few days on this I've found no reliable BB marionette way to sort on add AND filter on each keystroke a user list without rendering duplicate models. If I do I'll update. But I just think the benefit of the collection/view bond here is not fully realized without this piece. I did this with minimal difficulty in AS3.

I think the real answer is that views should accurately represent the state of a model. If a model has had an addition and been sorted, a view should reflect that. Duplicate model rendering feels like a bug.

UPDATE:

Learning as I go here. You have to specify in the override precisely where you want your content to go. As such, my 'ul' itemViewContainer is no longer relevant. So the final answer for me was:

  1. Ditch itemViewContainer
  2. Override appendHtml to tell my CompositeView explicitly where my users ul was and also to insert users by index according to sort order
  3. Ditch my "add" collectionEvent and handler

http://jsfiddle.net/QhQ8D/29/

Whew...


回答1:


Your doSort() function, triggering reset is what does the trick. If you comment that out, it only produces one copy of the view.

Use a comparator() function to sort the model, don't reset the list every time it is added.

UPDATE

More ideas on sorting as models are added are explained here:

The best way to sort a collection in a CompositeView

I used the appendHTML extension example in this post successfully in my own app (the first response to the question).



来源:https://stackoverflow.com/questions/19142492/backbone-marionette-compositeview-sorted-list-renders-extra-model-on-add

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!