Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One View connected to multiple models

Tags:

backbone.js

I have the following problem…

MyView which is connected to two views: TaskModel and UserModel

TaskModel = {id: 1, taskName: "myTask", creatorName: "myName", creator_id: 2 },
UserModel = {id: 2, avatar: "someAvatar"}

The view should display

{{taskName}}, {{creatorName}}, {{someAvatar}}

As you can see the fetch of TaskModel and UserModel should be synchronized, because the userModel.fetch needs of taskModel.get("creator_id")

Which approach do you recommend me to display/handle the view and the two models?

like image 986
antonjs Avatar asked May 21 '12 12:05

antonjs


People also ask

Can we use multiple models for single view?

You can use multiple models in a single view by creating a common model for all the models that are to be used in a single view. To achieve this, refer to the following steps. First, create a new model (common for all models) and refer all other models that are to be used in the same view.

Can one view have multiple controllers?

Yes, It is possible to share a view across multiple controllers by putting a view into the shared folder. By doing like this, you can automatically make the view available across multiple controllers.

How do you connect view models?

We can pass the data or communicate from Model to View by these three steps: Take the object in the action of a Controller. Pass Model object as a parameter to View. Use @model to include Model on the View page.


1 Answers

You could make the view smart enough to not render until it has everything it needs.

Suppose you have a user and a task and you pass them both to the view's constructor:

initialize: function(user, task) {
    _.bindAll(this, 'render');
    this.user = user;
    this.task = task;
    this.user.on('change', this.render);
    this.task.on('change', this.render);
}

Now you have a view that has references to both the user and the task and is listening for "change" events on both. Then, the render method can ask the models if they have everything they're supposed to have, for example:

render: function() {
    if(this.user.has('name')
    && this.task.has('name')) {
        this.$el.append(this.template({
            task: this.task.toJSON(),
            user: this.user.toJSON()
        }));
    }
    return this;​​​​
}

So render will wait until both the this.user and this.task are fully loaded before it fills in the proper HTML; if it is called before its models have been loaded, then it renders nothing and returns an empty placeholder. This approach keeps all of the view's logic nicely hidden away inside the view where it belongs and it easily generalizes.

Demo: http://jsfiddle.net/ambiguous/rreu5jd8/


You could also use Underscore's isEmpty (which is mixed into Backbone models) instead of checking a specific property:

render: function() {
    if(!this.user.isEmpty()
    && !this.task.isEmpty()) {
        this.$el.append(this.template({
            task: this.task.toJSON(),
            user: this.user.toJSON()
        }));
    }
    return this;​​​​
}

That assumes that you don't have any defaults of course.

Demo: http://jsfiddle.net/ambiguous/4q07budc/

like image 111
mu is too short Avatar answered Oct 16 '22 22:10

mu is too short