Go from one view to another, and then return to the initial view without losing the state that you had

0

I want to know if there is anything that I can take advantage of backbone that allows me to pass information from one view to another and then return to the view that initialized the second, without losing the data loaded.

This would be:

From the view1 I call the router and I get to the view2. View1 I pass parameters to view2. Vista2 does its job (in my case, looking for a record) and I have to return it to vista1, but vista1 has to keep all the state it has been maintaining and in some way (here the doubt) record what it sees happen to it.

That's my problem, I do not know how I have to return data to Vista1.

    
asked by franco gimenez 20.09.2017 в 19:08
source

1 answer

0

The views do not have a proper status. Rather, they depend on a model and what they draw should be obtained from the properties of the model. Since the model does have a state, any mutation you want to persist must be made on the model.

Before answering, I'm going to rename your variables:

  • vista1 will be called vistaPadre
  • Your constructor is called VistaPadreView
  • vista2 will be called vistaHija
  • Your constructor is called VistaHijaView

If you want vistaHija to have a status, you must pass it a model:

var Modelo1 = Backbone.Model.extend();
var VistaPadreView = new Backbone.View.extend();
var vistaPadre = new VistaPadreView({
     model: new Modelo1()
});
vistaPadre.render();

Now you say that the vistaHija is instantiated from the vistaPadre . This second view should also have an underlying model to run a fetch on it and thus refresh its data. According to the description of your question, the vistaHija makes a request that you yourself have armed perhaps using jQuery.ajax .

What you should do, instead, is declare an underlying model for vistaHija . That model should have as an attribute urlRoot the endpoint where you want to see the details of the record:

var Modelo2= new Backbone.Model.extend({
    urlRoot: '/buscaregistro/';
});

That way, by calling fetch within Modelo2 , if it has a id attribute, an ajax call will be executed at /buscaregistro/<id> .

Within the vistaHija you must have an associated event to the action of bringing the data, obtaining what you want to find (for example) by means of the value of an input with id #busqueda . For example:

var VistaHijaView = new Backbone.View.Extend({
  events: {
     'click .buscar': 'gatillaBuscar'
  },
  gatillaBuscar: function() {
    this.model.set('id', this.$('#busqueda').value());
    this.model.fetch().then(function(respuesta) {
       ...la respuesta contiene los detalles del registro...
    })
  }
});

var vistaHija = new VistaHijaView({
   model: new Modelo2()
});
vistaHija.render();

Then, suppose that the vistaPadre instantiates the vistaHija , and from there the user can search for a record using its id and get the details for it and pass them to vistaPadre . The right thing really would be to pass the details to the instance of Modelo1 and reinstate vistaPadre passing it this model, which now has its previous properties more which you just set within vistaHija .

Now, for vistaHija to be able to modify the instance of Modelo1 , it would have to have a reference to it. You can pass this reference when you instantiate it from vistaPadre .

Redefine then vistaPadre by adding an event that instantiates and renders the vistaHija passing not only the instance of Modelo2 but the instance of Modelo1 in the attributes .

var VistaPadreView=Backbone.View.extend({
   events: {
     'click #abrevistaHija': 'abrirVistaHija'
   }
   abrirVistaHija: function() {
      var vistaHija = new VistaHijaView({
         model: new Modelo2(),
         attributes: {
            modelo1: this.model
         }
      });
      vistaHija.render();
   }
});

Then, when rendering vistaHija , it has a reference to the instance of Modelo1 accessible as this.attributes.modelo1 (which within vistaPadre is accessed as this.model )

The method gatillaBuscar of view 2 should then do:

  gatillaBuscar: function() {
    var _this = this;
    this.model.set('id', this.$('#busqueda').value());
    this.model.fetch().then(function(respuesta) {
     _this.attributes.modelo1.set('detalle_registro', respuesta.attributes);
     var vistaPadre = new VistaPadreView({
        model: _this.attributes.modelo1
     });
     vistaPadre.render();
    });
  }

What you have done then is, from the views, to mutate models. The models retain their status. When reinstalls vistaPadre from vistaHija passing the reference to the instance of Modelo1 , it has the new state of its model.

Putting everything together:

var Modelo1 = Backbone.Model.extend();

var Modelo2= new Backbone.Model.extend({
    urlRoot: '/buscaregistro/';
});

var VistaPadreView=Backbone.View.extend({
   events: {
     'click #abrevistaHija': 'abrirVistaHija'
   }
   abrirVistaHija: function() {
      var vistaHija = new VistaHijaView({
         model: new Modelo2(),
         attributes: {
            modelo1: this.model
         }
      });
      vistaHija.render();
   }
});

var VistaHijaView = new Backbone.View.Extend({
  events: {
     'click .buscar': 'gatillaBuscar'
  },
  gatillaBuscar: function() {
    var _this = this;
    this.model.set('id', this.$('#busqueda').value());
    this.model.fetch().then(function(respuesta) {
     _this.attributes.modelo1.set('detalle_registro', respuesta.attributes);
     var vistaPadre = new VistaPadreView({
        model: _this.attributes.modelo1
     });
     vistaPadre.render();
    });
  }
});


var vistaPadre = new VistaPadreView({
     model: new Modelo1();
});
vistaPadre.render();

A shorter alternative path:

You do not even need to reinstate VistaPadreView because it could have been passed to vistaHija within the attributes. Instance vistaPadre continues to exist even if it is no longer in the DOM. So if within vistaPadre you do:

 var vistaHija = new VistaHijaView({
     model: new Modelo2(),
     attributes: {
        modelo1: this.model,
        vistaPadre : this
      }
 });
 vistaHija.render();

Then you could re-render the vistaPadre from vistaHija if gatillaBuscar was defined as:

gatillaBuscar: function() {
    var _this = this;
    this.model.set('id', this.$('#busqueda').value());
    this.model.fetch().then(function(respuesta) {
     _this.attributes.modelo1.set('detalle_registro', respuesta.attributes);
     _this.attributes.vistaPadre.render();
    })
  }

Since _this.attributes.vistaPadre is the original instance of vistaPadre and it is already associated with the instance of Modelo1 , the mutation you made on that model will already be incorporated when you re-render vistaPadre .

    
answered by 09.08.2018 в 21:24