Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js - how to handle "login"?

Tags:

Hi I'm trying to wrap my head around backbone.js for some days now but since this is my first MVC Framework, it's pretty hard.

I can easily get my Collections to work, fetching data from the server etc, but it all depends on first "logging" in per API-Key. I just don't know how to model this with a good MVC approach. (btw: I can't use the Router/Controller because it's a Chrome Extension)

The Flow looks like this:

  1. Start Extension
  2. Is there an API-Key in localStorage?
  3. No => Display a input field and a save button which saves the key to localStorage; Yes => proceed with the Application:
  4. App......

The only way I could think of it is putting it all together in a big View... but I guess since I am fairly new to this there are surely some better approaches.

like image 546
algorithms Avatar asked Aug 28 '11 09:08

algorithms


1 Answers

You can create a model that maintains the state of the user's login status and a view that renders a different template depending on that status. The view can show the "input field" template if the user is not logged in and a different template if the user is. I would keep all access to localStorage in the Model because the View should not be concerned with persistence. The view should probably not be concerned with the API Key as well, and that's why I have my view binding to the model's loggedIn change ('change:loggedIn') instead of apiKey change...although I am showing the API key in one of my templates for demonstration purpose only. Here's my very simplified sample. Note that I didn't bother with validating the API Key, but you'll probably want to:

Templates:

<script id="logged_in" type="text/html">     You're logged in.  Your API key is <%= escape('apiKey') %>. Let's proceed with the application... </script> <script id="not_logged_in" type="text/html">     <form class="api_key">         API Key: <input name="api_key" type="text" value="" />         <button type="sumit">Submit</button>     </form> </script> 

Backbone Model and View:

var LoginStatus = Backbone.Model.extend({      defaults: {         loggedIn: false,         apiKey: null     },      initialize: function () {         this.bind('change:apiKey', this.onApiKeyChange, this);         this.set({'apiKey': localStorage.getItem('apiKey')});     },      onApiKeyChange: function (status, apiKey) {         this.set({'loggedIn': !!apiKey});     },      setApiKey: function(apiKey) {         localStorage.setItem('apiKey', apiKey)         this.set({'apiKey': apiKey});     }  });  var AppView = Backbone.View.extend({      _loggedInTemplate: _.template($('#logged_in').html()),     _notLoggedInTemplate: _.template($('#not_logged_in').html()),      initialize: function () {         this.model.bind('change:loggedIn', this.render, this);     },      events: {         'submit .api_key': 'onApiKeySubmit'     },      onApiKeySubmit: function(e){         e.preventDefault();         this.model.setApiKey(this.$('input[name=api_key]').val());     },      render: function () {         if (this.model.get('loggedIn')) {             $(this.el).empty().html(this._loggedInTemplate(this.model));         } else {             $(this.el).empty().html(this._notLoggedInTemplate(this.model));         }         return this;     } });  var view = new AppView({model: new LoginStatus()}); $('body').append(view.render().el); 
like image 94
Johnny Oshika Avatar answered Jan 21 '23 23:01

Johnny Oshika