Backbone.js

IT/IT기술 2015. 8. 11. 00:03

웹어플리케이션 개발  시  프론트앤드단에서  MVC 패턴을 사용 할 수 있게 해주는 자바스크립트  언어로 만들어진 프레임워크
아래는  backbone.js에 대해서 잘 설명해 놓은 블로그의 글을 가져온 것 입니다.(하단 참조)

Backbone.js #진짜마지막 총정리

IntroductionTop

Backbone.js 연재를 마치면서 가장 중요한 부분들을 정리해드립니다. 핵심적인 내용이니 도움이 되실거라 굳게 밉습니다. ㅎㅎ

backbone

실무에서 Backbone.js 를 사용하면서 느낀 장점Top

  • 서버와 쉽게쉽게 대화할 수 있다.
  • 그리하여 나는 서버와 혼연일체가 될 수 있다.
  • 기존에 이렇게 구현하기 위해 Ajax 도배질을 했었다.
  • 비동기로 되면서 구조적으로 구현하기 어려웠다.
  • 점점 관리가 어려워졌다.
  • Backbone.js 가 스파게티 코드를 구조적으로 변경해주었다.
  • 고마웠다.
  • 역시 이름 그대로 documentcloud 회사 답다.

핵심구절 복습Top

- Backbone.js의 수십개의 메소드를 신경쓰지 마세요.

- underscore.js 수십개의 메소드를 신경쓰지 마세요.

- 단지 별거 아닌 유틸리티에요. !!

- 이것이 Backbone.js를 이해하는데 있어서 가장 큰 함정입니다 :-)

- 우리는 가지를 보는것이 아니라, 전체의 모습을 볼 거에요

tree

아래 키워드 (메소드/프로퍼티)는 꼭 잊지마세요.Top

메뉴얼에 나와있는 나머지 메소드/프로퍼티는 여러분의 눈을 현혹시키기 위한 OTU (Only Tiny Utility)

  • Model
    • Model.url
    • Model.urlRoot
    • Model.save()
    • Model.fetch()
    • Model.destroy()
    • Model.sync
    • Model.set
    • Model.add
    • idAttribute: 'id'
  • Collection
    • Collection.fetch()
    • Collection.create()
    • bind event 설정
      • add
      • reset
      • all
  • View
    • el property
    • events delegation
    • not template
    • use template module
      • Underscore template method
      • Mustache
      • etc..
    • with Model
      • event bind
        • change
        • destroy
    • with Collection
      • event bind
        • add
        • reset
        • all
    • View.remove()
  • Route
    • url change event 에 대해서 cross browser 처리
    • hash(#) / hashbang(#!) 링크연결
    • single page architecture

몇개 빠져있을 수도 있어요. ㅋ

Backbone.js's Objects DiagramTop

backbone.js objects diagram

  1. Collection 은 여러개의 Model 을 포함합니다.
  2. Model 은 독립적으로 혹은 Collection 의 Reference 로서 동작하고, 서버와 REST Communication 하면서 데이타를 Sync 합니다.
  3. 이와 동시에 Collection, Model 은 이벤트를 발생시켜, View와 Communication 하고 비동기적인 서버와의 응답결과를 체계적으로 전달합니다.
  4. 마지막으로 Route 는 브라우져에서 변경되는 URL 을 모니터링하여 정의한 URL Spec 에 binding 하여 체계적으로 연결합니다.

필수로 REST API 를 갖춘 웹서버를 준비하세요.Top

물론 준비하지 않아도 backbone.localStorage 으로 테스트가 가능합니다.

  • Rails
  • Node.js express
  • php laravel
  • python django

ModelTop

Model idAttributeTop

Backbone.js 의 가장 큰 컨셉은 서버와 쉽게쉽게 커뮤니케이션 하는 것입니다. 이렇게 하기 위해서는

  • 클라이언트에서 생성한 데이타는 서버와 통신 후 PK 를 업데이트하여 Sync
  • 서버에 입력되어 있는 데이타를 불러오면 클라이언트에서도 동일하게 구성

위 2가지 조건을 만족해야 하며, 이때 idAttribute property 가 중요한 역할을 하게 됩니다.

기본값은 id 이고, 데이타를 구분하는 primary key 명이 다르다면 변경하세요. 이것은 Model.save() 와 직접적으로 연관되고, insert / update 요청을 구분합니다.

참고로 1편에서 배웠죠. Mongodb의 id 명은 _id 라는것을... 이것 꼭 Model#idAttribute에 정의해야만 된다는 것을요.

  • var Todo = Backbone.Model.extend({
  • idAttribute: '_id'
  • });

자세한건 1편 POST편을 참조하세요.

Collection 정의하기Top

쉽게 생각하세요. 단지 Model 을 이루는 JSON 객체를 여러개 가지고 있다고요~~~

Collection 을 구성합니다. 별거 없고요. urlmodel property 만 선언해주세요.

  • window.TodoList = Backbone.Collection.extend({
  • url: '/api/todo',
  • model: Todo
  • });

Collection 구성은 아주 최소한으로 생성한 것입니다. 각각의 컨트롤하고 싶은 메소드는 입맛에 맞게 추가

Model + Collection 정의하기Top

  • window.TodoList = Backbone.Collection.extend({
  • url: '/api/todo',
  • model: Todo
  • });

Collection 선언시 model property 는 지정하지 않아도 model 객체를 참조합니다. 이렇게 지정할 때의 이유는 Model 에 기 정의된 메소드를 사용할 때 입니다.

서버와 통신하기 위한 url / urlRoot 지정은 필수 !! 지정하지 않을때는 url property 지정하지 않았다고 에러발생

Collection 에서 발생하는 이벤트 사용하세요Top

  • window.AppView = Backbone.View.extend({
  • el: $('#todoapp'),
  • initialize: function() {
  • window.Todos = new TodoList();
  • Todos.bind('add', this.addOne, this);
  • Todos.bind('reset', this.addAll, this);
  • Todos.fetch();
  • }
  • });

Collection 객체를 생성합니다. 해당 Collection에 Model관련 addreset 이벤트에 대한 trigger를 선언합니다. 그리고, Collection#fetch 메소드를 사용하여 서버로부터 데이타 (read (GET))를 불러옵니다. 이때,Collection reset event 가 발생합니다.

Collection 객체는 복잡한 구조를 가진 객체인데, 어떻게 underscore.js 의each 메소드를 사용하여 model 을 반복자에 전달시킬 수 있는가?Top

이것은 여기에 답이 있습니다.

  • // Underscore methods that we want to implement on the Collection.
  • var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
  • 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
  • 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
  • 'max', 'min', 'sortedIndex', 'toArray', 'size', 'first', 'head', 'take',
  • 'initial', 'rest', 'tail', 'last', 'without', 'indexOf', 'shuffle',
  • 'lastIndexOf', 'isEmpty'];
  • // Mix in each Underscore method as a proxy to `Collection#models`.
  • _.each(methods, function(method) {
  • Collection.prototype[method] = function() {
  • var args = slice.call(arguments);
  • args.unshift(this.models);
  • return _[method].apply(_, args);
  • };
  • });

Collection은 undersocre.js 함수를 내장하고 있는데, 그대로 사용하지 않고, Collection 객체의 models property를 전달하여 오버라이드 하고 있습니다. 아셨죠? 그래서 each하면 Collection 이 반복되는것이 아니였고, Collection의 models property 가 반복될 수 있는것입니다.

Collection 을 each 로 반복시켰고, 전달되는 model 을 찍어보면 복잡한 객체인데, 어떻게 JSON.stringify 를 사용하여 Model의 Data를 심플하게 JSON 으로 확인할 수 있는가?Top

Backbone.js 의 Model#toJSON 메소드가 정의 되어 있습니다. JSON.stringify 메소드가 전달된 객체에 toJSON 메소드가 정의되어 있으면 그것을 사용 합니다. 즉, 전달된 Model 객체에 toJSON 메소드가 정의되어 있기 때문에 자연스럽게 오버라이드 되어지는 것입니다. 그래서, backbone.js toJSON 에 의해 Model 의 attributes 만 쏙 빠져나오게 됩니다. 아셨죠?

서버와 통신시에 wait 옵션을 사용할때도 있어요Top

Collection#create 메소드를 사용하여 Model을 Collection 에서도 간단히 만들 수 있습니다. 이때, Collection add event 가 발생하게 되는데, underscore template에서 _id` 값이 없으므로 에러를 반환합니다. 무슨 얘기냐면...

wait option

  • true: 서버와 통신하여 응답을 받으면 collection add event 발생
  • false: 서버와 통신전에 collection add event 발생

즉, Collection#create 메소드에 wait: true 옵션을 전달하여, _id 값이 선언된 Model 이 반환되게 해야합니다. 그러므로, wait 값을 true 으로 선언하여 _id 값이 Model에 설정되게 한 후 화면에 표시하게 합니다.

  • createTodo: function(e) {
  • if (e.keyCode != 13) return;
  • Todos.create({ title: $('#new-todo').val() }, { wait: true });
  • }

View 객체 작성시 참고하세요.Top

  • View 객체를 작성된 HTML에 적용하기 위해서는 el property를 필수로 선언해야 합니다. 왜냐하면, View 객체는 기본적으로 events property에 선언한 이벤트가 el property 에 선언된 엘리먼트에 적용되기 때문입니다.
  • 목록에 반복되는 게시글은 1개의 View 객체와 1개의 Model 객체로 구성하는것이 구조적으로 다루기에 편합니다.
    • Model 데이타가 변할시
    • Model 데이타가 삭제될 시
    • Model 데이타가 매핑되는 template 에 event delegation 할 시
  • 즉, View객체를 생성할 때 Model 객체를 전달합니다.

Client Template Module 사용하세요.Top

  • script#item-template(type="text/template")
  • <td><a href="#<%= _id %>"><%= title %></a> ::: <input type="button" value="del" data-action="del"></td>

HTML을 제발 Javascript 영역으로 가지고 들어오지 마세요

HTML 에 기정의된 Element에 View 를 정의하기 위해서는 엘리먼트를 el property 에 정의하셔야 해요.Top

  • window.AppView = Backbone.View.extend({
  • el: $('#todoapp'),
  • });

View에서 tagName 선언Top

  • window.TodoView = Backbone.View.extend({
  • tagName: 'tr',
  • });

기본값은 div 입니다. 반복되는 엘리먼트의 tagName 을 변경할 때는 필수로 선언해주셔야 해요.

TABLE > TBODY 영역에 TR 태그를 넣을때 같이 말이죠.

View 객체를 생성시에는 Model 을 전달해주세요.Top

underscore#bind 함수를 이용하여 Collection event에 대한 trigger를 선언했습니다. 이것이 실행되면 이벤트가 발생한 Collection의 Model이 trigger에 전달됩니다. 위에서 설명한 Todo ItemView 에 Model 을 전달한다고 했습니다. 바로 이 부분입니다. 1개의 ItemView가 1개의 Model을 컨트롤 한다 !!!! 그리하여 todo item view 에서 생성한 tr~ 엘리먼트를 table > tbody에 붙입니다.

  • addOne: function(todo) {
  • var view = new TodoView({ model: todo });
  • $('#todo-list tbody').append(view.render().el);
  • },

Anchor Element에 Hash 링크를 선언하여 Route 객체와 연결하세요Top

  • script#item-template(type="text/template")
  • <td><a href="#<%= _id %>"><%= title %></a> ::: <input type="button" value="del" data-action="del"></td>

HTML에 정의한 template 부분에 a element 에 선언한 Hash(#) 링크가 Route 객체와 연결됩니다.

  • var Workspace = Backbone.Router.extend({
  • routes: {
  • ":id": "search"
  • },
  • search: function(id) {
  • console.log(arguments);
  • }
  • });
  • window.Route = new Workspace();
  • Backbone.history.start();

게시판 Diagram 을 그려서 구조적인 생각을 정립해보세요.Top

아래 그림은 Backbone.js 을 이루는 객체를 어떻게 사용할 것인가에 대한 구체적인 계획을 수립해 줍니다. Backbone.js 에서는 이런것이 중요하다는것을 잊지 마세요

구체적인 내용은 아래와 같습니다.

  • View 객체를 어떻게, 어느부분에 사용할 것인가?
  • View 객체를 어떻게 구조적으로 Model 객체 과 연관시킬 것인가?
  • Model 객체를 어떻게 구성하여 View 객체 와 연동하고 이벤트를 제어할 것인가?
  • Collection 객체 영역을 알아보고, 전체 View 객체 와 어떻게 연동할 것인가?



실무 경험상 막상 Backbone.js를 이루는 Model, Collection, View 를 구조적으로 사용할려고 하면 막연한 공상만 떠올르게 됩니다. 저는 머리가 그리 좋지 않아요 :-) 위와 같이 그림을 그리고 구상해보면 조금이나마 Model, Collection, View 사용계획이 정립되어 진다는 것을 알려드리고 싶습니다.

고급 into the backbone.jsTop

  • 이곳 에서는 Backbone.sync 수행되고 나서 Backend 로부터 반환된 데이타를 Model.set 에 전달하는 것을 확인할 수 있습니다.-
  • Model.set 은 기존 Model 데이타와 비교 를 하여 이를 동기화 시킵니다.
  • 이곳 에서는 Model.set 수행될 때, id attribute를 검사하는 것을 확인할 수 있습니다.
  • 이곳 에서는 Model.save 수행 시 Backbone.sync에 POST와 PUT중에 어떤 method 를 전달할지 정하는 프로세스를 확인할 수 있습니다.
  • 이때 필요한 idAttribute를 확인하는 아주 아주 중요한 isNew 함수 확인하시고요. :-)
  • 이곳 에서는 Model.fetch 수행 시 Backbone.sync에 read (GET) 프로세스를 확인할 수 있습니다.
  • 이곳 에서는 urlRoot 를 Model 에 설정하면, 3편에서 url 을 함수로 지정하여 구분설정하지 않아도, 자동으로 새로운 데이타여부(id 유무)를 판단하여 url 에 id 가 붙게 되는것을 확인할 수 있습니다.

ConclusionTop

휴, 진짜 끝입니다. 누락된 부분이 있다면 총정리 2편이 나올 수도 있습니다. ;; 읽어주셔서 감사합니다.

추천 관련글Top

  1. [cookbook] Backbone.js Model 총정리 / 전체 Diagram Introduction
  2. Node.js MVC framework - Stack Overflow
  3. Sitemap - Node.js QA 게시판
  4. balderdashy/sails · GitHub
  5. What is the best "full stack web framework" (with scaffolding, MVC ...
  6. cookbook - Node.js QA 게시판
  7. Sails.js | The future of API development - GitHub Pages
  8. [cookbook] RailwayJS MVC Framework Preview - Node.js QA 게시판
  9. [cookbook] Sequelize #1 개념과 CRUD (Nodejs에서도 ORM 사용 ...
  10. Home · visionmedia/express Wiki · GitHub

[참고] http://nodeqa.com/nodejs_ref/53#7Iuk66y07JeQ7IScIEJhY2tib25lLmpzIOulvCDsgqzsmqntlZjrqbTshJwg64qQ64KAIOyepeygkA==


'IT > IT기술' 카테고리의 다른 글

1. JPA ( java persistance api) 란?  (0) 2015.08.20
[resthub] Spring F/W + Backbone.js ( 예제 프로젝트 실행 )  (0) 2015.08.12
부트스트랩(Bootstrap)  (0) 2015.08.11
Posted by wychoi
,