How to remove everything you need from the main view?

Hi, my attempt to delete everything caused the close function in the search view file after running the previous or next function using this.close (), but it deleted the view that completely affected the navigation function ... I was wondering how to delete everything after completion otherwise vent.on happens several times in the router.

Here is my router file:

define([ 'jquery', 'underscore', 'backbone', 'views/page', 'models/search', 'views/search', 'text!templates/search.html', 'models/song', 'text!templates/song.html' ], function($, _, Backbone, PageV, SearchM, SearchV, SearchT, SongM, SongT) { var vent = _.extend({}, Backbone.Events); var currentView, page, search; Backbone.View.prototype.close = function () { this.remove(); this.unbind(); if (this.onClose) { this.onClose(); } }; var AppRouter = Backbone.Router.extend ({ routes: { 'page/:id': 'showPage', 'search': 'showView' } }); var initialize = function () { var app_router, songPages; app_router = new AppRouter; vent.on('loadPage', function (id) { console.log('hit loaded page'); var newPage = 'page/' + id; if(id < songPages && id >= 0 ) { app_router.navigate(newPage, true); } else { app_router.navigate('search', true); } }) console.log('router file hit'); app_router.on('route:showPage', function (id) { console.log('page rendered'); var songs, collected, songM, start; songM = new SongM(); songM.localStorage = new Backbone.LocalStorage("music"); songM.localStorage.findAll().forEach(function (i) { collected = i; }); songPages = Math.ceil(collected.music.length / 25); //10 pages start = id * 25; songs = collected.music.splice(start, 25); var titles = { week: collected.week, year: collected.year, channel: collected. channel }; var currentId = parseInt(id); if (page) {console.log('page is current'); console.log(page); page.remove(); } page = new PageV({model: songM, collection: songs, vent: vent, titles: titles, theId: currentId }); page.render(id); //$("#Sirius").html(page.el); }); app_router.on('route:showView', function () { console.log('search page loading...'); var cur; var searchM = new SearchM(); //if (search) {console.log(search); search.remove(); } search = new SearchV({model: searchM, vent: vent}); //if(cur) {cur.stopListening(); cur.remove(); console.log('cur removed'); } search.render(); //cur = search; vent.on('nextPage', printCons); function printCons () { console.log('changing pages'); app_router.navigate('page/0', true); }; }); Backbone.history.start(); }; return { initialize: initialize }; }); 

Here is the page with the page:

  define([ 'jquery', 'underscore', 'backbone', 'models/song', 'collections/songs', 'views/song', 'text!templates/page.html', 'text!templates/song.html' ], function($, _, Backbone, Song, Songs, SongV, PageT, SongT){ var Page = Backbone.View.extend({ el: $("#Sirius"), events: { "click .prev": "previous", "click .next": "next" }, previous: function () { this.options.vent.trigger('loadPage', this.options.theId - 1); }, next: function () { this.options.vent.trigger('loadPage', this.options.theId + 1); }, render: function () { var headings = this.options.titles; var info = { week: headings.week, channel: headings.channel, year: headings.year } var pagetemp = _.template( PageT, info); this.$el.html( pagetemp ); var songColl = this.collection; var songV = new SongV({collection: songColl}); songV.render(); } }); return Page; }); 
0
javascript jquery
Oct 28 '13 at 20:15
source share
1 answer

This is because you reuse the same DOM element, #Sirius , every time you create a view. When initializing a view, Backbone delegates DOM events to their top level node wrapped in $el .

When a view is deleted, cleanup is performed automatically, since node is removed from the DOM. Since you replace node HTML without deleting it, event handlers are never deleted, so your old views respond to click events even after their contents are no longer in the DOM.

There are several ways to handle this.

  • When rendering plug-in content, do not render it directly into the DOM element. Rather, treat it like a container and make it inside it. This way you can remove the view without affecting the original DOM. This is a general approach for areas of pages with consistent views.

     // somewhere in a higher scope, refer to the page. Note that if you // don't need to do any cleanup (Events bindings, model cleanup, etc), you // don't *need* to keep this reference. var page; // in your show handler, replace the *contents* of the DOM element rather // than creating a 2nd view attached to it. This means removing the `el` // from the view prototype, as well. if (page) page.remove(); page = new Page(...); page.render(); $("#Sirius").html(page.el); 
  • Reuse the same view, updating its instance variables instead of replacing. This is especially important for pagination, where you repeat the collection of content, but the structure remains the same.

     // somewhere in a higher scope (or on app.page, etc) var page; // on the view, clean up the process of "updating" settings with a method, // something like: update: function (options) { this.model = options.model; this.collection = options.collection; this.options = options; } // then in your show handler, create a new view the first time, then just // update it rather than replacing it page || (page = new PageV()); page.update(options); 
  • Clear delegated event bindings from the DOM element. I am embarrassed to add this, since both 1 and 2 are more suitable, but any of these approaches will probably work:

     // kludge level 1: reference the searchview and attempt to clean it if (page) { page.undelegateEvents(); page.stopListening(); // if available // any other cleanup } page = new PageV(...); // kludge level 2: unbind all DOM events from the element $("#Sirius").off(); var page = new PageV(...); // kludge level 3: replace the element in the DOM $("#Sirius").replaceWith('<div id="#Sirius" />'); var page = new PageV(...); 

Do not # 3. 1 or 2 are more suitable.

+1
Oct 28 '13 at 21:10
source share



All Articles