Структурирование моего приложения backbone.js - PullRequest
3 голосов
/ 08 ноября 2011

Я в процессе создания приложения Backbone.js с помощью Require.js. Каждый файл представления соответствует одному ресурсу (например, «Новости»). В каждом файле представления я объявляю основу просмотр для каждого действия («индекс», «новый» и т. д.). Внизу файла просмотра я получаю необходимую информацию от маршрутизатора и затем решить, какое представление создать (на основе информации, переданной от маршрутизатора).

Все это работает хорошо, но требует большого количества кода и не похоже на 'backbone.js way'. Во-первых, я полагаюсь на URL для управления состоянием. Во-вторых, я не использую _.bind, который появляется во многих примерах из backbone.js. Другими словами, я не думаю, что я делаю это правильно, и моя база кода пахнет ... Есть мысли о том, как лучше структурировать мое приложение?

router.js

define([
  'jquery',
  'underscore',
  'backbone',
  'views/news'], 
  function($, _, Backbone,  newsView){
    var AppRouter = Backbone.Router.extend({
        routes:{
            'news':'news',
            'news/:action':'news',
            'news/:action/:id':'news'
        },

        news: function(action, id){
            newsView(this, action, id).render();
        }
    });


    var intialize = function(){
        new AppRouter;
        Backbone.history.start()
    };

    return{
        initialize: initialize;
    };
}

news.js ('views / news')

define([
  'jquery',
  'underscore',
  'backbone',
  'collections/news',
  'text!templates/news/index.html',
  'text!templates/news/form.html'

  ], function($, _, Backbone, newsCollection, newsIndexTemplate, newsFormTemplate){

    var indexNewsView = Backbone.View.extend({
        el: $("#content"),

        initialize: function(router){
            ...
        },

        render: function(){
            ...
        }
    });

    var newNewsView = Backbone.View.extend({
        el: $("#modal"),

        render: function(){
            ...
        }
    });

    ...

    /*
     *  SUB ROUTER ACTIONS
     */

    var defaultAction = function(router){
      return new newsIndexView(router);
    }

    var subRouter = {
      undefined: function(router){return defaultAction(router);},

      'index': function(router){ return defaultAction(router);},

      'new': function(){
        return new newNewsView()
      },

      'create': function(router){
        unsavedModel = {
          title : $(".modal-body form input[name=title]").val(),
          body  : $(".modal-body form textarea").val()
        };
        return new createNewsView(router, unsavedModel);
      },

      'edit': function(router, id){
        return new editNewsView(router, id);
      },

      'update': function(router, id){
        unsavedModel = {
          title : $(".modal-body form input[name=title]").val(),
          body  : $(".modal-body form textarea").val()
        };

        return new updateNewsView(router, id, unsavedModel);
      },
    }

    return function(router, action, id){
      var re = /^(index)$|^(edit)$|^(update)$|^(new)$|^(create)$/
      if(action != undefined && !re.test(action)){
        router.navigate('/news',true);
      }
      return subRouter[action](router, id);
    }


  });

Ответы [ 3 ]

6 голосов
/ 08 ноября 2011

Хотя я чувствую, что важно подчеркнуть, что на самом деле «Backbone.js way» не существует, похоже, вы копируете работу, которую Backbone должен делать для вас.

Я согласен, что имеет смысл иметь специализированный маршрутизатор для каждого независимого раздела вашего приложения. Но на первый взгляд кажется, что то, что вы делаете в разделе «суб-маршрутизатор», просто воссоздает функциональность Backbone.Router. Ваши AppRouter вообще не должны иметь дело с /news URL; Вы можете просто инициализировать NewsRouter маршрутами, связанными с новостями, и он будет работать с URL-адресами, связанными с новостями:

var NewsRouter = Backbone.Router.extend({
    routes:{
        'news':             'index',
        'news/create':      'create',
        'news/update/:id':  'update',
        'news/edit/:id':    'edit'
    },

    index: function() { ... },

    create: function() { ... },

    // etc
});

Пока это инициализируется перед вызовом Backbone.history.start(), он будет перехватывать запросы URL для своих маршрутов, и вам никогда не придется иметь дело с AppRouter. Вам также не нужно иметь дело с уродливым фрагментом кода внизу вашего представления - это в основном просто делает то, что делает для вас ядро ​​Backbone.Router.

2 голосов
/ 08 ноября 2011

Я также использую require.js и магистраль. Я думаю, что основное отличие, которое я бы предложил, заключается в том, что каждый файл должен возвращать только один вид, модель, маршрутизатор или коллекцию.

, поэтому моей главной html-странице требуется мой основной маршрутизатор. Этот маршрутизатор является модулем, который требует нескольких представлений, основанных на каждом из его маршрутов, и загруженной модели. Каждый метод маршрутизатора передает соответствующий загруженный фрагмент модели в соответствующее представление.

Оттуда он остается действительно чистым, если каждый файл представляет собой всего одну магистральную вещь (модель, коллекция, представление, маршрутизатор) и требует только те элементы, которые он использует. Это приводит к большому количеству js-файлов (у меня есть около 100 для моего текущего проекта), но именно здесь в игру вступает оптимизация require.js.

Надеюсь, это поможет.

0 голосов
/ 08 ноября 2011

Почему бы вам не структурировать свои маршруты так:

        routes:{
            'news':'news',
            'news/edit/:id':'editNews',
            'news/new':'newNews',
            ...
        }
...