2014-08-28 1 views
3

Je ne comprends pas comment partager une sorte de modèle d'objet de maintien d'état d'application "singleton" entre différentes vues, en utilisant browserify. Livres et tutoriels utilisent souvent un espace de noms global tels que:Browserify + Backbone.js Module partagé "ApplicationState"

var app = app || {}; 

J'ai une application simple exemple qui consiste à:

app.js

var $ = require('jquery'); 
var Backbone = require('backbone'); 
Backbone.$ = $; 

var MenuView = require('./views/MenuView'); 
var ContainerView = require('./views/ContainerView'); 

new MenuView(); 
new ContainerView(); 

MenuView.js

var Backbone = require('backbone'); 
var ApplicationState = require('../models/ApplicationState'); 

module.exports = Backbone.View.extend({ 
    el: '#menuView', 
    events: { 
     'click .menuLink': 'changePage' 
    }, 
    changePage: function(event) { 
     event.preventDefault(); 
     var viewName = $(event.target).attr('data-view'); 
     ApplicationState.set('currentView',viewName); 
    } 
}); 

ContainerView.js

var Backbone = require('backbone'); 
var ApplicationState = require('../models/ApplicationState'); 

module.exports = Backbone.View.extend({ 
    el: '#containerView', 
    initialize: function() { 
     this.listenTo(ApplicationState, 'change', this.render); 
     this.render(); 
    }, 
    render: function() { 
     this.$el.html(ApplicationState.get('currentView')); 
    }, 
    close: function() { 
     this.stopListening(); 
    } 
}); 

Cela semble fonctionner en utilisant cette approche:

ApplicationState.js var Backbone = require ('épine dorsale');

var ApplicationState = Backbone.Model.extend({ 
    defaults: { 
     currentView: 'TransactionListView' 
    } 
}); 

module.exports = new ApplicationState(); 

Le module ApplicationState est-il réellement créé une seule fois (mise en cache)? Ou existe-t-il un risque de recréer/réinitialiser le module?

Quelle est la meilleure pratique pour mon cas d'utilisation? Merci beaucoup.

+0

Je suppose qu'il est ok, vous pouvez vérifier le nombre de cas ApplicationState sera créé en ajoutant console.count ('Application State') dans le fichier ApplicationState.js et voir la sortie dans la console. –

+0

'this. $ El.html (ApplicationState.get ('currentView'));' devrait probablement être 'this. $ El.html (ApplicationState.get ('currentView'). $ El);' –

Répondre

5

Oui, il n'y aura qu'un seul ApplicationState dans l'exemple que vous avez donné. Browserify exécute tout ce qui suit module.exports = dès que le fichier js est exécuté, puis tout ce qui nécessite ce fichier est passé une référence au résultat.

Toutefois, il est généralement préférable d'éviter de partager l'état de cette manière entre les vues et d'utiliser à la place une vue parente qui délègue aux sous-vues. Il y a plusieurs façons de configurer cela. Pour des idées sur les meilleures pratiques pour l'organisation d'une application backbone, consultez cette discussion: https://www.youtube.com/watch?v=Lm05e5sJaE8

Pour l'exemple que vous avez donné, je considérerais fortement l'utilisation de Backbone's Router. Dans votre exemple, vous avez un nav qui change la vue "principale". Backbone.Router intercepte la navigation et la vérifie par rapport à vos itinéraires spécifiés en appelant votre méthode d'affichage. Par exemple:

router.js

module.exports = Backbone.Router.extend({ 
    initialize: function(options){ 
     this.ContainerView = new ContainerView(); 
    }, 
    routes: { 
     'transactions': 'showTransactionListView', 
     'transaction/:id': 'showTransactionDetailView' 
    }, 
    showTransactionListView: function() { 
     this.ContainerView.render('TransactionListView'); 
    }, 
    showTransactionDetailView: function(id) { 
     this.ContainerView.render('TransactionDetailView', id); 
    } 
}); 

Puis tout lien vers #transations (ou tout simplement transactions si vous utilisez Backbone History) appellera votre ContainerView.render('TransactionListView'). Et, en prime, si vous rechargez la page, vous regarderez toujours TransactionListView.

Autres notes:

  • Vous voulez vous assurer que vous défausser de vieux vues lorsque vous les remettrez (en appelant .remove() sur eux) afin d'éviter les fuites de mémoire.Further Reading
  • Vous pouvez ajouter une certaine flexibilité à votre routeur et utiliser un modèle de contrôleur pour rendre subviews avec this nifty plugin
+0

Ok merci beaucoup bien, je vais jeter un coup d'oeil à la conversation. Pouvez-vous m'expliquer comment les routeurs s'intégreraient dans mon exemple, s'il vous plait? Merci encore! –

+1

Bien sûr. J'ai mis à jour ma réponse avec un exemple de routeur (minimal). – Marshall

Questions connexes