Search code examples
javascriptbackbone.jsmodel-view-controller

Passing a Model instance to an already initialized Backbone View


I would like to pass the Model of a View to an already initialized View here.This is the View that has the data,it can be considered an ItemView of the Collection:

var app=app||{};
app.ContactView=Backbone.View.extend({
  tagName:'li',
  className:['contact-view'],
  model:app.Contact,
  events:{
    'click .editing-icon':'showEditView'
  },
  initialize:function contactViewInit(){
    this.render();
    this.listenTo(this.model,'change',this.render);
  },
  template:Handlebars.templates.contactView,
  render:function contactViewRender(){
    var html=this.template(this.model.toJSON());
    this.$el.html(html);
    return this;
  },
  showEditView:function(){
    //show edit view...this should also be handled by app view...
    //(1)how do I pass a message to editview;how can I generate an event in Backbone
    app.EditView.set({
     //there is an error here...
      model:this.model
    });
  }
});

This is the View which should recieve the data,it is based on static html which opens a modal and prompts the user to edit the model data which will re-render the first view,it has already been initialized because I think there is no point in initializing it repeatedly:

  var app=app||{};

var EditView=Backbone.View.extend({
  el:'#edit-modal',
  initialize:function initializeEditView(){
    console.log("Initializing Modal for editing");
    console.log(this.model.toJSON());
    this.$form=this.$el.find("form");
    this.initializeEditForm();
    this.showYourself();
  },
  initializeEditForm:function initializeEditForm(){
    this.$form.find('#edit-name').val(this.model.get('name'));
    this.$form.find('#edit-email').val(this.model.get('email'));
    this.$form.find('#edit-phone').val(this.model.get('phone'));
  },
  showYourself:function showYourself(){
    this.$el.modal('show');
  },
  hideYourself:function hideYourself(){
    clearEditForm();
    this.$el.modal('hide');
  },
  clearEditForm:function clearEditForm(){
    this.$form.find('#edit-name').val('');
    this.$form.find('#edit-email').val('');
    this.$form.find('#edit-phone').val('');
  },
  events:{
    'click #edit-contact button':'submitEditedData'
  },
  submitEditedData:function submitEditedData(){
      var data={
          name:this.$form.find('#edit-name').val(),
          phone:this.$form.find('#edit-phone').val(),
          email:this.$form.find('#edit-email').val()
      };
      console.log("Data recieved from the edit form");
      this.model.set(data);
      this.hideYourself();
  }
});

app.EditView=new EditView();

I have an AppView which handles creating data with a html form,should I instead have handled this there?

UPDATE:

This is the AppView that I built in order to handle creating a model and adding it to the collection(which will cause a collection view to render this item view and add it to the collection):

 var app=app||{};
app.AppView=Backbone.View.extend({
  el:'#app',
  initialize:function appInit(){
    //mostly caching selectors here
    this.$form=this.$('#new-contact');
    this.$contactList=this.$('#contacts-list');
  },
  events:{
    'click #new-contact button':'createContact'
  },
  createContact:function createContact(e){
    e.preventDefault();

    //build a model based on form and clear the form
    var contact=this.createModelUsingForm();
    this.clearForm();
    //add model to the collection
    app.ContactsCollection.add(contact);
  },
  createModelUsingForm:function createModelUsingForm()
  {
    var data=this.processFormForContact();
    var contact=new app.Contact(data);
    return contact;
  },
  processFormForContact:function processFormForContact()
  {
    return {
      name:this.$form.find('#name').val(),
      phone:this.$form.find('#phone').val(),
      email:this.$form.find('#email').val()
    };
  },
  clearForm:function clearForm(){
    this.$form.find('#name').val('');
    this.$form.find('#email').val('');
    this.$form.find('#phone').val('');
  }
});

Solution

  • Consider triggering an event from the ContactView that passes the model back to a central controller. The controller can then listen for this event and react accordingly, i.e., instantiate the EditView using the model it receives from the event.