Clear localStorage and change the view Backbone

2020-02-13 06:25发布

问题:

Hey so I am using backbone localstorage and every time someone hits the search button I want to clear the localstorage so I can just add the new data to the localStorage.

Also, trying to figure out how to then redirect the user to a new view after the success callback in for the localstorage being set, I know there is view.remove() but I am not sure how to use that being that the callback is within the view and also, where/how to render the new view...

Let's say the new view is PageView...

Here is the code for the current search view:

    define([
  'jquery',
  'underscore',
  'backbone',
  'models/search',
  'text!templates/search.html',

], function($, _, Backbone, SearchM, SearchT){ 

  var Search = Backbone.View.extend({
    model: SearchM,
    el: $("#Sirius"),

    events: {
      'submit #searchMusic': 'search'
    },
    search: function (e) {
      e.preventDefault();

      //create new instance of the model
      searchM = new SearchM();

      //post instance to the server with the following input fields
      searchM.save({
        channel: this.$('#channel').val(),
        week: this.$('#week').val(),
        year: this.$('#year').val(),
        filter: this.$('#filter').val()
      },{success: storeMusic});

      // on success store music on client-side localStorage
      function storeMusic (model, response, options) {
        console.log('store');
        //create new instance of the localStorage with the key name
        searchM.localStorage = new Backbone.LocalStorage("music");
        clearLocalStorage();
        saveToLocalStorage(response);
      };
      function clearLocalStorage () {
        console.log('clear');
          //removes the items of the localStorage
          this.localStorage.clear();

          //pops out the first key in the records
          searchM.localStorage.records.shift();

        };
        function saveToLocalStorage (response) {
          console.log('save');
          searchM.save({music: response}, {success: nextPage});
        };
         function nextPage () {
          console.log('entered next page');
          searchM.set('display', true);
        };


    },
    render: function () { 

    }
  });
    return Search;
});

Container view:

define([
  'jquery',
  'underscore',
  'backbone',
  'views/search',
  'text!templates/search.html'
], function($, _, Backbone, SearchV, SearchT){ 

  var Container = Backbone.View.extend({
    el: $("#Sirius"),
    render: function () { 
      var search = new SearchV();
      this.$el.html( SearchT );
      this.listenTo(searchM, 'change:display', console.log('changed MODEL'));
    }

      });
    return Container;
});

Here is the model:

define([
  'underscore',
  'backbone'
], function(_, Backbone) {

  var Search = Backbone.Model.extend({
    url: '/music',
    defaults: {
        display: false
    }

  });
  return Search;
});

----------------EDIT Confused with below

This is the container and SearchM(model), SearchV(view), SearchT(template)...

var Container = Backbone.View.extend({
    el: $("#Sirius"),
    render: function () { 
      //Model CREATED
      searchM = new SearchM();

     //VIEW Created
      var search = new SearchV();
      this.$el.html( SearchT );
    }
      });
    return Container;
});

This is the search View - so I took out the model from here, but calling this or this.model actually does not work, as searchM is not defined and the model does not seemed to be passed in... I only added the two methods so ignore the rest for now, if I can make these work then everything can follow suit

var Search = Backbone.View.extend({

    el: $("#Sirius"),

    events: {
      'submit #searchMusic': 'search'
    },
    search: function (e) {
      e.preventDefault();



      //post instance to the server with the following input fields
      searchM.save({
        channel: this.$('#channel').val(),
        week: this.$('#week').val(),
        year: this.$('#year').val(),
        filter: this.$('#filter').val()
      },{success: storeMusic()});

     function nextPage () {
          console.log('entered next page');
          searchM.set('display', true);
          this.listenTo(searchM, 'change:display', console.log('changed MODEL'));
          console.log(searchM.display);
        };

回答1:

Try this to get rid of the model:

searchM.destroy();

That's basically the same as in my answer here, but for a single model.

As for the view changing, i would recommend adding a 'display' or 'loaded' variable to the model, which is false by default and set to true, when the data is ready. Then, have the view listen to the 'change:display' event, triggering the render() method when ready. You can delete the old view, as soon as you know the data has changed and replace it with some loading spinner, which then will be replaced by the new data view. Hope this helped.

Confused parts:

var Container = Backbone.View.extend({
    el: $("#Sirius"),
    render: function () { 
      //Model CREATED
      searchM = new SearchM();

     //VIEW Created
      var search = new SearchV({model: searchM});
      this.$el.html( SearchT );
    }
});

var Search = Backbone.View.extend({

    el: $("#Sirius"),

    events: {
      'submit #searchMusic': 'search'
    },
    initialize: function () {
         this.listenTo(this.model, 'change:display', this.displayChanged);
    },
    displayChanged: function () {
       console.log('display changed');
    },
    search: function (e) {
      e.preventDefault();
      //post instance to the server with the following input fields
      searchM.save({
         channel: this.$('#channel').val(),
         week: this.$('#week').val(),
         year: this.$('#year').val(),
         filter: this.$('#filter').val()
      },{success: storeMusic()});
    },
    nextPage: function () {
        console.log('entered next page');
        searchM.set('display', true);
        console.log(searchM.display);
    },


回答2:

I haven't used Backbone.LocalStorage before, and the documentation doesn't specify how you should clear the data, however, in the source code there is a _clear() method that should do the trick:

function listStore (model, response, options) {
        searchM.localStorage = new Backbone.LocalStorage("music");
        searchM.localStorage._clear();
        searchM.save({music: response}, {success: console.log('success')
});

As for switching to a new View, that is generally handled using a Backbone.Router which will handle redirecting your users to any area of your application you wish.

var MyRouter = Backbone.Router.extend({

  routes: {
    "search/:query":        "search",  // #search/kiwis
    "page":                 "page"   // #page
  },

  page: function() {
    new PageView(); //etc...
  },

  search: function(query) {
    ...
  }

});

//this line is required to tell Backbone that your routes are ready
Backbone.history.start(); 

Once you have the appropriate routes established, you can navigate to the desired location by calling:

function listStore (model, response, options) {
            //check to see if the LS exists, and clear it if so
            if(searchM.localStorage){
               searchM.localStorage._clear();
            }
            searchM.localStorage = new Backbone.LocalStorage("music");
            searchM.save({music: response}, {success: console.log('success');
            searchM.on('sync', function(){
               MyRouter.navigate("page", {trigger: true});
            });
    });