Какой хороший способ построить проект Backbone.js? - PullRequest
9 голосов
/ 19 августа 2011

Мы сейчас запускаем наш первый Backbone.js проект здесь, на работе.Фактически это наш первый крупный JavaScript-проект, за исключением странных jQuery.

Во всяком случае, мы боремся с архитектурой для наших вещей.Каков наилучший способ разобраться?

Мы начали с того, что все в отдельных файлах разбиты на папки для;представления, модели, коллекции и маршрутизаторы, а затем мы включаем все в нашу index.html.Проблема, однако, в том, что это оставляет нам необходимость проверять событие готовности документа в каждом файле.Это лучший способ сделать это?

Вот пример:

Этот файл называется PageModel, первая строка кажется неправильной ...

$(function(){
     app.models.Page = Backbone.Model.extend({
    //stuff
    });
});

Тогда в нашем index.html мы имеем:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title></title>

        <link href="assets/css/style.css" rel="stylesheet" type="text/css" />

        <script type="text/javascript">
            var app            = app                 || {};

            app.models         = app.models         || {};
            app.collections    = app.collections     || {};
            app.views        = app.views         || {};
            app.routers        = app.collections     || {};
            app.templates     = app.templates        || {};

            app.models.griditems = app.models.griditems || {};
            app.views.griditems = app.views.griditems || {};
        </script>

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
        <script src="assets/js/libs/json2.js" type="text/javascript"></script>
        <script src="assets/js/libs/underscore-1.1.7.min.js" type="text/javascript"></script>
        <script src="assets/js/libs/backbone-0.5.3.min.js" type="text/javascript"></script>

        <script src="assets/js/models/GridItemModel.js" type="text/javascript"></script>
        <script src="assets/js/models/GalleryGridItemModel.js" type="text/javascript"></script>
        <script src="assets/js/models/NewsGridItemModel.js" type="text/javascript"></script>
        <script src="assets/js/models/VideoGridItemModel.js" type="text/javascript"></script>

        <script src="assets/js/collections/GridCollection.js" type="text/javascript"></script>

        <script src="assets/js/templates/Submenu.js" type="text/javascript"></script>
        <script src="assets/js/templates/GalleryGridItemTemplate.js" type="text/javascript"></script>

        <script src="assets/js/views/GridView.js" type="text/javascript"></script>
        <script src="assets/js/views/GridItemView.js" type="text/javascript"></script>
        <script src="assets/js/views/GalleryGridItemView.js" type="text/javascript"></script>
        <script src="assets/js/views/VideoGridItemView.js" type="text/javascript"></script>

        <script src="assets/js/routers/Router.js" type="text/javascript"></script>

        <script src="assets/js/Application.js" type="text/javascript"></script>
    </head>

    <body>
    </body>
</html>

Ответы [ 2 ]

4 голосов
/ 12 сентября 2011

Если вы создаете приложение этой формы, я настоятельно рекомендую использовать динамическую загрузку ваших активов, таких как javascript и т. Д.

у вас есть несколько вариантов для этого:

У меня самого нет опыта работы с LABjs, ноЯ использовал Require.js в небольших проектах для себя.Но еще не использовать его в крупном проекте.

преимущества такой системы:

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

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

Я предлагаю вампрочитайте ' начало работы с require.js ' и посмотрите, не хотите ли вы его использовать.

, потому что работа со всеми моделями / видами / ... в отдельных файлах довольно удобна в разработкеЭто важно, но не рекомендуется при запуске в производство.чем меньше запросов должно быть отправлено браузером на сервер, тем лучше.

4 голосов
/ 19 августа 2011

Это структура, которую мы используем в наших проектах Backbone

<!-- Libs Section -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery-1.5.2.min.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery.validate.min.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery.maskedinput-1.3.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery.mousewheel.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery.scrollpane.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/fileuploader.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/modernizr.min.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/json2.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/underscore-min.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/backbone-min.js")"></script>
<!-- Libs Section -->

<!-- Core Section -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/config.js")"></script> <!-- Global configs -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/core.js")"></script> <!-- Core methods for easier working with views, models and collections + additional useful utils -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/app.js")"></script> <!-- Application object inherites core.js as prototype -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/renisans.js")"></script> <!-- Project Object. Creates Namespace and Extends it with project specific methods -->
<!-- Core Section -->

<!-- Routers Section -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/routers/workspace.js")"></script>
<!-- Routers Section -->

<!-- Models Section -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/models/profile.js")"></script>
    ...
<!-- Models Section -->

<!-- Collections Section -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/collections/messages.js")"></script>
    ...
<!-- Collections Section -->

<!-- Views Section -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/views/workspace.js")"></script>
    ...
<!-- Views Section -->

<!-- Localization Section -->
    <script type="text/javascript" src="@Url.Content("~/Content/static/js/localizations/ru_RU.js")"></script>
<!-- Localization Section -->

<!-- Init Section -->
    <script type="text/javascript">
        $(function() {
            Rens.container = $('.l-wrapper'); // Some parameters
            Rens.init({
                Localization: LocalizationStrings || {}, // Object with localization strings
                Profile: {
                    // Bootstraping initial data to Profile model
                }
            });
        });
    </script>
<!-- Init Section -->

содержимое app.js

var App = function() {
        this.Views = {};
        this.Routers = {};
        this.Models = {};
        this.Collections = {};
        this.User = {};

        this.router = null;
        this.view = null;
        this.baseLocation = null;

        this.beforeInit = function() {};
        this.afterInit = function() {};

        this.init = function(initData) {
            if (typeof(this.beforeInit) === 'function') {
                this.beforeInit.apply(this, arguments);
            }

            if (this.Views.Workspace) {
                this.view = new this.Views.Workspace();
            }
            this.baseLocation = window.location.href.replace(/[?#].*/, '') == Config.web.host;

            if (this.Routers.Workspace) {
                this.router = new this.Routers.Workspace(initData);
            }
            this.view && this.view.setListeners && this.view.setListeners();
            Backbone.history.start();

            if (typeof(this.afterInit) === 'function') {
                this.afterInit.apply(this, arguments);
            }
        }.bind(this);
    };

App.prototype = Core;

и содержимое renisans.js

var Rens = new App();

$.extend(Rens, {
    container: null,

    Error: function(data) {
        // Handling error
    },

    Localization: function(dictionary) {
        return {
            get: function(name) {
                var argumentsList = Array.prototype.slice.call(arguments),
                    strings = argumentsList.slice(1),
                    text = this[name];

                if (text && strings.length) {
                    $(strings).each(function(i, string) {
                        var reg = new RegExp('\\$' + i, 'go');

                        text = text.replace(reg, string);
                    });
                }
                return text || 'SLB.Localization.' + name + ' not found!';
            }.bind(dictionary)
        }
    },

    formatDate: function(rawDate) {
        var timestamp = /\d+/.exec(rawDate)[0],
            date = Rens.DateUTC(timestamp),
            months = Rens.Localization.get('months');

        return {
            date: date,
            fullDate: [date.dd, months[date.mm], date.hh].join(' '),
            shortDate: [date.dd, date.MM, date.hh].join('.')
        };
    },

    beforeInit: function(initData) {
        this.Localization = new this.Localization(initData.Localization);
    }
});

также упрощено содержание моделей / profile.js

Rens.Models.Profile = Backbone.Model.extend({
    ...
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...