Question

I have created a very basic backbone application, but I need to perform a slightly complex check which I am having trouble doing.

My code is below. What I'm doing here is creating a list of participants in a chat. In reality, I will be sending this list in through a javascript function.

   Participant = Backbone.Model.extend({});

    Participants = Backbone.Collection.extend({
        model: Participant
    });

    ParticipantView = Backbone.Marionette.ItemView.extend({
        template: "#participant-template",
        tagName: 'div',
        className: 'call-participant',

        initialize: function () {
            this.$el.prop("id", this.model.get("chatid") + "-" + this.model.get("participantName"));
        },
    });

    ParticipantsView = Backbone.Marionette.CompositeView.extend({
        template: "#participants-template",
        tagName: 'div',
        itemView: ParticipantView,

        appendHtml: function(collectionView, itemView) {
            collectionView.$el.append(itemView.el);
        }
    });

    MyApp.addInitializer(function(options)) {
        var participantsView = new ParticipantsView({
            collection: options.participantNames
        });
        MyApp.participantContainer.show(participantsView);
            var participantsModel = new Participants();
    };

    $(document).ready(function() {        
        MyApp.start({participantsModel: participantsModel});
    })

The trouble I am having is that when people leave/join the chat, the message is being resent with a new participant list (e.g. some participantName values won't be there).

So to the question: In backbone.marionette, how and where do I tell it to compare the existing models to the new list of models (for a give chatid), and if the model is no longer in the list, remove the model, and if there's something in the list that isn't a model, add it. You will see I am building my ID from the the chatid AND the participantName (note that the name is unique, it is actually the JID I'm sending without the @server). The reason the ID is formatted like this is that I will have around 5-10 lists on one page, so I don't want to start updating the wrong chats.

Thank you. Please ask if you require additional information. jsFiddle: http://jsfiddle.net/966pG/175/

Kind Regards,

Gary Shergill

EDIT: I am aware of get and set, but in all honesty have no idea how to use them. I've tried reading about them "http://backbonejs.org/#Model-get".

EDIT: Live scenario below. I have a javascript function which listens for pubsub events, and when it receives the right one it creates an array of participant objects:

    var participants = [];
    $(iq).find('participants').each(function() {
        var participantsNodes = this.childNodes;
        for (var i = 0; i < participantsNodes.length; i++) {
            var participantAttr = participantsNodes[i].attributes
            var participant = participantAttr[0].nodeValue;
            participants.push({"participantName": participant, "chatid": chatid});
        }
    });
    var chatid = $(iq).find('chatid').text();
    ...

                participantsModel.add(new Participants({
                    chatid : chatid,
                    participantArray : participants
                }))
Was it helpful?

Solution

Based on conversation in the comments

Backbone's Collection.set function takes care of this for you. You can add a new set of participants and it will recognize which ones are new, which ones are old and will fire add and remove events appropriately.

You need to add an array of Participants though, you can't just add an array of names. You can handle that with map pretty easily though.

//array of names from sonewhere
arr = getNamesFromServer()
arrOfParticipants = arr.map(function(name) {
  id = calculateChatID(name,/*whatever else you need */)
  return new Participant(name:name,chatID: id);
}

participantNames.set(arrOfParticipants)

Exactly how you keep track of your participants and where you pull in updates is up to you.

Of course if you can get the information formatted into the correct format on the server, (an array of json objects matching Participant), you should just use Backbone's built in sync functions, which will handle all of this for you. Then, once you've set up a RESTful URL that matches your client side naming scheme, or overriden the url property on your model/collection, you can just call participantNames.fetch().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top