Exchange / exchange / exchange of data backbone.js in place?

I am using view / edit Views in backbone.js for the contact manager. On the Internet, it is proposed to create a Contact class with child views of ContactView and ContactEdit. The problem is that they must occupy the same ale in the DOM, so I cannot nest children inside the parent. This is because from the outside, I want the parental views to concern only Contact, as if the children were private. I tried this and it works the first time I render ():

initialize: function() { this.view[0] = new CL.Views.ContactView({model: this.model, el: this.el}); this.view[1] = new CL.Views.ContactEdit({model: this.model, el: this.el}); }, render: function() { this.view[0].render(); return this; } 

But then I canโ€™t change my mind. I tried this.view [0] .remove () and all I can think of, but just can't get the view and edit the views to share with each other using the same el.

I think this means that it is better to have two templates inside the same view and just exchange them, which already basically works. I think backbone.js does not handle inheritance well for representations at the same level in the DOM.

I would prefer to avoid backbone.js extensions, but I have to keep an eye on any templates that they implement. I am trying to do this in the โ€œrightโ€ way, because viewing / editing is such a common template for forms in our application.

PS Another way to state this problem: how to hide the view and replace it with another view in backbone.js if there is no parent view that surrounds them?

Thanks in advance for any help you can provide.

+6
source share
3 answers

I donโ€™t quite understand if you want to have a view for the Collection of Models or do you want the view to concern one Model ?

If this view is for one model,

then you can stick to one look. Just listen to some events that enable you to enable or disable editing features. (You can do this even by setting contenteditable = "true" to dom elements)

I highly recommend using some tools like backbone.marionette or chaplinjs. They will save you a ton of time.

The following are examples for Backbone.Marionette

template example

 <script type="text/template" id="contact-view-template"> <span data-bind="firstName"></span> <span data-bind="lastName"></span> <span data-bind="email"></span> <a href="#" data-action="edit"> <a href="#" data-action="save" style="display:none"> </script> 

View Code:

 ContactView = Marionette.ItemView.extend({ template:"#contact-view-template", events:{ "click [data-action=edit]":"edit", "click [data-action=save]":"save" }, edit:function(){ this.$("[data-action=edit]").hide(); this.$("[data-action=save]").show(); this.$("[data-bind]").attr("contenteditable",true); }, save:function(){ var value = {}; _.each(this.$("[data-bind]",function(el){ value[el.dataset['bind']]= $(el).val() || $(el).text(); })); this.model.set(value); // add your validation here this.model.save(); } }); 

If you want to have several views, and not just:

 ContactListEditView = Marionette.CompositeView.extend({ itemView:ContactView.extend({ tagName:"li" }), itemViewContainer:"ul", template:_.template("<h1>ContactList</h1><p>feel free to edit</p><ul></ul>") }); 

If you need 1 type of editing and several non-editable types

(I hope I have not made serious mistakes):

 ContactEditView = Marionette.ItemView.extend({ template:"#contact-edit-view", // your template & bindings events:{ "click [data-action=save]":"save" }, save:function(){ var value = {}; _.each(this.$("[data-bind]",function(el){ value[el.dataset['bind']]= $(el).val() || $(el).text(); })); this.model.set(value); this.model.save(); } }); ContactListView = Marionette.CompositeView.extend({ itemView:Marionette.ItemView.extend({ template:"#contact-view-template", events:{ "click [data-action=edit]":"edit" }, edit:function(){ this.trigger("edit",this); } }), regions:{ "edit":"[data-region=edit]" }, initialize:function(){ this.on("itemview:edit",function(view){ this.edit.show(new ContactEditView({model:view.model})); }.bind(this)); } }); 
+1
source

I think your problems are due to the fact that your parent view shares the same element with the child views. When you render a ContactView or ContactEdit , it replaces the DOM element, and when you remove child view, it (by definition) also removes the parent element of the view, since they are the same element.

Instead, you must create a parent view so that the child view appears in the container element. Sort of

 <!-- .contact-container is the parent view el --> <section class="contact-container"> </section> 

And then render the child views in the container:

 initialize: function() { //don't give the views an element, let them render into the detached //element generated by Backbone this.view[0] = new CL.Views.ContactView({model: this.model}); this.view[1] = new CL.Views.ContactEdit({model: this.model}); this.currentViewIndex = 0; }, render: function() { //replace the contents with the new view this.view[this.currentViewIndex].render(); this.$el.html(this.view.el); return this; }, swap: function() { var i = this.currentViewIndex; this.view[i].remove(); //toggle current view between 0 and 1 this.currentViewIndex = i === 0 ? 1: 0; this.render(); } 

Then you get

 <!-- .contact-container is the parent view el --> <section class="contact-container"> <div><!-- your child element --></div> </section> 
0
source

If I understand your question correctly, you need a view that inherits from the View base so that they can work freely with the same Model .

 /** Declare base View with specific Model. */ var baseView = Backbone.View.extend({ model: someModel }); var contactView = baseView.extend({ initialize: function() { /** Do work specific to contact view. */ } }); var editContactView = baseView.extend({ initialize: function() { /** Do work specific to contact edit. */ } }); var mainView = Backbone.View.extend({ initialize: function() { /** Initialize two contact views */ new contactView({ }); new editContactView({ }); } }); 
0
source

All Articles