다음은 매우 큰 백본 응용 프로그램에서 작업 한 후의 몇 가지 팁입니다. 그것은 두 개의 디렉토리, 예를 들어
또한 당신은 당신의 빌드 작업 그것은 build/
또는 dist/
디렉토리에 배포 버전으로 응용 프로그램을 구축 할 것을 실행할 때. Gulp 나 Grunt를 사용했을 수도 있습니다.
백본을 확장
귀하의 전체 응용 프로그램은 다음과 같이 구성됩니다
- 조회수 & 하위 뷰
- 라우터 & 서브 라우터
- 모델
- 컬렉션
처음에는 비어있는 경우에도 백본 클래스를 확장해야합니다. 가장 유용한 두 가지 확장 기능은 다음과 같습니다
- 하위 뷰 (뷰는 상위 뷰를 제거 할 때 정리 얻을 더 뷰와
views
객체/기능을 가질 수있다). model
또는 collection
이라는 모델 및 모음이 자동으로 하위보기로 전달됩니다.
- 하위 라우터
사용 포드 아키텍처로
주위에 당신의 응용 프로그램을 구성 (이 좋다 모듈 폴더 내의 각 모듈에 대한 라우팅 로직을 가지고) 독립적 인 모듈 예 :
www/app/modules/home/router.js
< - 서브 라우터는 modules.js의 메소드를 호출합니다.
www/app/modules/home/module.js
< - 레이아웃 변경,보기 초기화 의 & 모델 등
www/app/modules/home/views/...
모든 뷰
www/app/modules/home/templates/
(너무 하위 폴더를 가질 수 있습니다) www/app/modules/home/models/
www/app/modules/home/collections
시작 뷰의 규정 및 하위 뷰
있는 페이지 아무튼에서 응용 프로그램을보고 ' 단지 하나의 견해로 구성됩니다. 그것은 아마도 특별한 "레이아웃"뷰를 가질 것이고 내부에는 많은 뷰가있을 것입니다. 하나는 페이지를 반으로 나눕니다. 하나는 페이지 번호별로 더 많은 뷰가있는 페이지 매김이 있으며, 내부에는 많은 하위 뷰가있는 폼의 뷰입니다. 각 양식 요소 및 메시지 등에 대해
DOM 트리를 음영 처리하고 논리적으로 분할하는 것으로 생각할 수 있습니다. 페이지에서 재사용 가능하다고 생각되는 항목은 패키지로 만듭니다 (자체보기 및 모델/모음입니다). 필요하다면).
모델은 서버/api/데이터베이스에서 뷰가 아무것도 표시하지 않으면 일반적으로 뷰에 전달되어 모델 속성 전체 또는 일부를 템플리트에 전달하는 데이터 및 데이터에 대해 수행 된 모든 논리에 대한 것입니다. .
는 광범위 트리거 및 수신을 사용하여 응용 프로그램을 통해 통신 할 수 AppState 서비스라는 모델을 작성 앱 상태를 되세요. 당신은 당신이 할 수있는 다시 사용 가능한 생각 앱에서 물건을 건너 때마다
도 다른 미래의 앱에 패키지를 만들, (옵션) 패키지 폴더 되세요. 이들은 일반적으로 자신의 git repos에서 호스팅되며 package.json 또는 명령 줄을 사용하여 프로젝트로 가져올 수 있습니다. 예를 들어, -
여러 앱에서 소비하는 모듈에 대한 확장 폴더가 당신이 간 응용 프로그램 물건 을 확장 폴더를 가지고 귀하의 백본 확장이 여기에 갈 수 있습니다. 또는 양식 용 패키지를 만들었지 만이 응용 프로그램 용으로 특별히 작업하려면 여기에서 확장하십시오.
www/app/extensions/view.js
www/app/extensions/model.js
는 "버튼"패키지에서 링크보기를 확장
www/app/extensions/collection.js
www/app/extensions/buttons/link.js
// .
www/assets/css
: 나는 공공 www/
폴더에 app/
폴더가 왜
자산
이유는 나 또한 글꼴 및 이미지 등 거기에 자산 폴더를 가질 수 있도록이다 www/assets/images
참고 : 모듈 폴더에 자산을 보관하고 싶을 수도 있습니다 (포드 아키텍처로 인라인). 나는 이것을 전에하지 않았지만 고려할만한 가치가있다.
index.html을 당신이 CommonJS를 사용 또는 AMD 당신의 index.html을 그냥 실제 DOM 요소 보일러 것이다 당신이 항목의 js 파일이 하나의 전화를했을 일반적 경우
. 디바이스에서 실행 그래서 (비 빌드) RequireJS가 app/config.js
을로드하지만 빌드에서 전체 응용 프로그램 것
<!--IF NOT BUILD-->
<script data-main="/app/config" src="/packages/require.js"></script>
<!--ELSE
<script src="/app.js"></script>
-->
: CommonJS 컴파일해야하기 때문에 이것은 단지 <script src="/app.js"></script>
같은 것을 할 것이지만, AMD 것이 더 같은 것 app.js
에 있습니다. 다양한 Grunt/Gulp 빌드 작업을 통해 위와 같은 작업을 수행 할 수 있습니다 (조건부 구문이 작성된 것임).
레이아웃
내가 extensions/view.js
확장하는 extensions/layout.js
을 만들 것이며, 정상적인 같은 하위 뷰 (예 : 머리글과 바닥 글)을 가질 수있는 간단한 확장뿐만 아니라, 내가 어떤을 첨부 할 수있는 특별한 서브 뷰 것 보기 (예 : 본문 하위보기) 방법은 setContentView(view)
입니다.
나는 layouts라는 모듈을 만들고 거기에 머리말과 꼬리말 subviews가있는보기가있는 modules/layout/default
디렉토리를 가지고있을 것이다. 그런 다음 인덱스 경로에 도달하면이 같은 것을 흐를 것 :
app/router.js => app/modules/home/router.js => app/modules/home/[email protected] => setContentView(view from app/modules/home/views/index.js)"
라우팅을
나는이 응용 프로그램 라우터가 예를 들어,에있는 것 당신이 필요 확장에 (주 같은과 일반 백본 라우터를 확장하여
subRouters: {
'store-locator': StoreLocatorRouter,
myaccount: MyAccountRouter,
sitemap: SitemapRouter
}
내가이 가능하게합니다 : 어떤 특별한 경로를 가질 수 있지만, 대부분 단지 하위 라우터에서 지적 객체와 subroute 것 www/app/router.js
) initialize
에 initSubRouters
전화 -
define([
'underscore',
'backbone'
],
function(_, Backbone) {
'use strict';
/**
* Extended Backbone Boilerplate Router
* @class extensions/router
* @extends backbone/view
*/
var Router = Backbone.Router.extend(
/** @lends extensions/router.prototype */
{
/**
* Holds reference to sub-routers
* @type {Object}
*/
subRouters: {},
/**
* Adds sub-routing
* based on https://gist.github.com/1235317
* @param {String} prefix The string to be prefixed to the route values
*/
constructor: function(options) {
if (!options) {
options = {};
}
var routes = {}, prefix = options.prefix;
if (prefix) {
// Ensure prefixes have exactly one trailing slash
prefix.replace(/\/*$/, '/');
} else {
// Prefix is optional, set to empty string if not passed
prefix = '';
}
if (prefix) {
// Every route needs to be prefixed
_.each(this.routes, function(callback, path) {
if (path) {
routes[prefix + '/' + path] = callback;
} else {
// If the path is "" just set to prefix, this is to comply
// with how Backbone expects base paths to look gallery vs gallery/
routes[prefix + '(/)'] = callback;
}
});
// Must override with prefixed routes
this.routes = routes;
}
// .navigate needs subrouter prefix
this.prefix = prefix;
// Required to have Backbone set up routes
Backbone.Router.prototype.constructor.apply(this, arguments);
},
/**
* Sets up 'beforeRoute' event.
*/
initialize: function() {
// This is a round about way of adding a beforeRoute event and must
// happen before any other routes are added.
Backbone.history.route({
test: this.beforeRoute
}, function() {});
},
/**
* Called before routes.
* @return {Boolean} false This ensures the 'route' is disabled.
*/
beforeRoute: function() {
Backbone.history.trigger('beforeRoute');
return false;
},
/**
* Adds prefix to navigation routes
* @param {String} route Non-prefixed route
* @param {Object} options Passed through to Backbone.router.navigate
*/
navigate: function(route, options) {
if (route.substr(0, 1) !== '/' && route.indexOf(this.prefix.substr(0,
this.prefix.length - 1)) !== 0) {
route = this.prefix + route;
}
Backbone.Router.prototype.navigate.call(this, route, options);
},
/**
* Initializes sub-routers defined in `this.subRouters`
*/
initSubRouters: function() {
_.each(this.subRouters, function(Router, name) {
this[name] = new Router({
prefix: name
});
}, this);
}
});
return Router;
});
훌륭한 답변, 감사합니다 Dominic! 나는이 템플릿으로 프로젝트를 재구성하기 시작했고, 이미 훨씬 더 조직화되어 있습니다. 몇 가지 후속 질문이 있습니다. 모든 페이지에 표시 될 헤더의 부분 템플릿이있는 경우 (다른 요소를 기반으로하는 동적 인 경우에도) 확장 프로그램 폴더에 배치해야합니까? 모든 모듈? 또한 뷰와 하위 뷰가있는 경로를 클릭하면 응용 프로그램 흐름을 설명 할 수 있습니까? 마찬가지로, 하위보기를 호출하는 기본보기 내에서 기본보기 -> 메소드를 호출하는 router -> method ...? 감사! –
@ user918065 Np 추가 정보를 추가했습니다. 나는 막연하게 어떤 것들을 만졌을 뿐더러 붙어 있다면 Qs에 자유롭게 물어보십시오. 그리고 자신의 리포지토리와 패키지로 패키지를 만드는 것에 대해 걱정할 필요가 없을 것입니다. –
감사! 빠른 질문 : 내 서브 라우터는 링크를 통해 탐색 할 때 작동하지만 URL로 직접 이동할 때는 작동하지 않습니다. 그 상황에서 서브 라우터는 절대로 호출되지 않습니다. –