블로그 이미지
윤영식
Frontend Application Architecter, Full Stacker, KnowHow Dispenser and Bike Rider

Publication

Statistics Graph

Recent Comment

2013.03.15 17:49 Backbone.js

서점 샘플 응용하기 - 01 에 이어서 02 에서는 서버-Node.js & MongoDB- 와 붙이는 작업을 한다. 원문이 과거 버전이어서 좀 더 이해하기 쉽도록 재구성하였고, RESTful API 테스트 방법도 새롭게 시도해 보았다



1) RESTful API 와 Node.js 환경 구성하기 

  - 호출하는 API 목록

/api/rides  GET 모든 라이딩정보의 배열을 얻는다.

/api/rides/:id  GET 아이디가 :id인 라이딩정보을 얻는다.

/api/rides  POST  새로운 라이딩정보를 추가하고 아이디가 추가된 그 정보를 반환한다.

/api/rides/:id  PUT 아이디가 :id인 라이딩정보를 수정한다.

/api/rides/:id  DELETE  아이디가 :id인 라이딩정보를 삭제한다.


  - node.js & mongodb 설치되어 있음을 가정하고 node.js 모듈을 설치한다

// 모듈 설치

$ npm install express

$ npm install mongoose


  - public 디렉토리를 생성하여 img, js, css, index.html 파일을 public 디렉토리 밑으로 옮긴다 

  


  - server.js 코딩하기

// 모듈 의존성

var express = require("express"); //웹 프레임워크


// 서버를 생성한다

var app = express();


// 서버를 설정한다

app.configure(function () {

    app.use(express.bodyParser()); //요청 바디를 파싱해서 req.body를 만든다

    app.use(express.methodOverride()); //HTTP 메쏘드를 덮어쓰기 위해서 req.body를 확인한다

    app.use(app.router); //url과 HTTP 메쏘드에 기반한 라우팅을 수행한다

    app.use(express.static(__dirname + '/public')); //정적 자원을 제공하는 곳

    app.use(express.errorHandler({ dumpExceptions:true, showStack:true })); //개발시점에 모든 에러를 보여준다

});


// 서버를 구동한다

app.listen(8080, function () {

    console.log("Express server listening on port %d in %s mode", 8080, app.settings.env);

});


  - nodemon 을 통해서 구동하기 : 수정된 코딩이 있으면 자동으로 restart node 수행 (nodemon 블로깅)

nodemon server.js

15 Mar 14:37:11 - [nodemon] v0.7.2

15 Mar 14:37:11 - [nodemon] watching: ~/backbone/riding

15 Mar 14:37:11 - [nodemon] starting `node server.js`

Express server listening on port 8080 in development mode


  - MongoDB 구동하기 

// mongod 데몬 실행 

$ mongod --dbpath /mongodb/ride_database/

Fri Mar 15 15:33:19 [initandlisten] MongoDB starting : pid=50361 port=27017 dbpath=/Users/nulpulum/mongodb/ride_database/ 64-bit host=mac-42-retina.local

Fri Mar 15 15:33:19 [initandlisten] db version v2.2.3, pdfile version 4.5

... 중략 ..

Fri Mar 15 15:33:19 [websvr] admin web console waiting for connections on port 28017

Fri Mar 15 15:33:19 [initandlisten] waiting for connections on port 27017

// Node.js 서버가 구동 되어 있으면 연결 정보가 출력된다 

Fri Mar 15 15:34:27 [initandlisten] connection accepted from 127.0.0.1:61129 #1 (1 connection now open)

Fri Mar 15 15:34:27 [initandlisten] connection accepted from 127.0.0.1:61130 #2 (2 connections now open)

Fri Mar 15 15:34:27 [initandlisten] connection accepted from 127.0.0.1:61131 #3 (3 connections now open)

Fri Mar 15 15:34:27 [initandlisten] connection accepted from 127.0.0.1:61132 #4 (4 connections now open)



2) Mongoose 통하여 MongoDB 접근하기 

  - biz.js 파일을 생성하고 mongoose 코딩하기

    + Mongoose 용 schema와 model을 만든다 

    + MongoDB 에 접속한다 

    + 모듈패턴으로 업무 callback CRUD function 들을 GET, POST, PUT, DELTE 메소드를 정의한다

  - server.js 안에 RESTful API 추가하기

.. 중략 ..

// 서버를 설정한다

app.configure(function () {

    app.use(express.bodyParser()); //요청 바디를 파싱해서 req.body를 만든다

    app.use(express.methodOverride()); //HTTP 메쏘드를 덮어쓰기 위해서 req.body를 확인한다

    app.use(app.router); //url과 HTTP 메쏘드에 기반한 라우팅을 수행한다

    app.use(express.static(__dirname + '/public')); //정적 자원을 제공하는 곳

    app.use(express.errorHandler({ dumpExceptions:true, showStack:true })); //개발시점에 모든 에러를 보여준다

});


// mongoose 업무모듈인 biz.js 가져오기 

var biz = require("./biz");


// RESTful API에 대한 호출에 대하여 biz.js 모듈의 callback 펑션을 설정함

app.get( '/api/rides', biz.readAll);

app.post('/api/rides', biz.create);

app.get( '/api/rides/:id', biz.read);

app.put( '/api/rides/:id', biz.update);

app.delete('/api/rides/:id', biz.delete);


// 서버를 구동한다

app.listen(8080, function () {

    console.log("Express server listening on port %d in %s mode", 8080, app.settings.env);

});



3) RESTful API 테스트하기 

  - Chrome extention 인 "Advanced REST client" 설치한다 : Chrome Web Store에서 검색하고 설치하면 됨


  - Advanced REST client 실행

    + POST 메소드를 선택 (GET, PUT, DELETE 순으로 실행하여 본다)

    + 하단의 Form 탭을 선택하여 key=value 를 추가한다 

    + "Send" 버튼을 클릭하면 결과가 최하단에 나온다 (200 OK)

          

 - MongoDB에서 결과 조회

$ mongo

MongoDB shell version: 2.2.3

connecting to: test

> show dbs

local (empty)


// POST가 성공하면 데이터베이스가 보인다 

> show dbs

local (empty)

ride_database 0.203125GB

> use ride_database

switched to db ride_database

> show collections

rides

system.indexes

> db.rides.find().toArray();

[

{

"title" : "투어 드 코리아",

"rider" : "윤복자",

"ridingDate" : ISODate("2013-06-01T00:00:00Z"),

"keywords" : "코리아 싸이클링",

"_id" : ObjectId("5142ccbd1b06d36acc000001"),

"__v" : 0

}

]

>


  - PUT 은 URL 뒤에 MongoDB document의 _id 값인  5142ccbd1b06d36acc000001  을 붙여준다. (DELETE 도 동일)

   



4) Backbone.js 와 Node.js 연결하기 

  - 클라이언트 <-> 서버 연결

    + MongoDB사용시 : _id 지정하기 

    + url 설정 : /api/rides

    + fetch() 호출

    + reset callback으로 render 설정

  - ride.js 백본파일을 수정 : 라이딩 정보 목록 가져오기 == 컬렉션 모델에서 url 설정

   var Ride = Backbone.Model.extend({

        defaults:{

            coverImage:"img/my_cycle.png",

            title:"2011년 대관령 대회",

            rider:"Yun YoungSik",

            ridingDate:"2011",

            keywords:"대관령 힐크라이밍 대회"

        },

        idAttribute: "_id"  // MongoDB 사용시 바꾸어줌 

        // idAttribute 와 같은 효과를 같는다 

        /*parse:function (response) {

            console.log(response);

            response.id = response._id;

            return response;

        }*/

    });

.. 중략 ..  

    // rides 

   /* var rides = [{title:"대관령 힐크라이밍 대회", rider:"Yun YoungSik", ridingDate:"2010", keywords:"대관령"},

        {title:"미시령 힐크라이밍 대회", rider:"Yun DoWon", ridingDate:"2011", keywords:"미시령"},

        {title:"투어 드 코리아", rider:"Yun YoungSik", ridingDate:"2012", keywords:"코리아"}];*/

    var rides = [];   // 위의 샘플은 사용하지 않고 빈 배열을 만들어 준다 

  

    ////////////////////

    // Ride Collection

    var Rides = Backbone.Collection.extend({

        model : Ride,

        url : '/api/rides'  // 서버 호출 API

    });


    ///////////////////

    // Collection View

    var RidesView = Backbone.View.extend({

        el: $("#rides"),


        initialize: function(){

            this.collection = new Rides(rides);

            // 서버로 부터 데이터 가져오기 

            this.collection.fetch();

            this.render();

            // 컬렉션 add가 호출되면 renderRide를 trigger 한다 

            this.collection.on("add", this.renderRide, this);

            this.collection.on("remove", this.removeRide, this);

            // fetch()가 비동기적이기 때문에 Backbone이 reset을 호출하면 trigger 될 수 있도록 한다 

            this.collection.on("reset", this.render, this);  

        },

.. 중략 ..


  - 브라우져 호출 : MongoDB 의 데이터를 가져와서 Backbone이 데이터를 reset 하게 되면 입력한 라이딩정보가 출력된다 

   


  -  날짜가 이상하게 나오므로 jQuery를 이용하여 날짜를 포멧팅 해준다 

<script id="rideTemplate" type="text/template">

        <img src="<%= coverImage %>"/>

        <ul>

            <li><%= title %></li>

            <li><%= rider %></li>

            <!-- 년/월/일 만 표현 --> 

            <li><%= $.format.date(new Date(ridingDate), 'yyyy/MM/dd') %></li>

            <li><%= keywords %></li>

        </ul>

        <button class="delete">Delete</button>

    </script>

</div>

<script src="js/jquery.js"></script>

<!-- 다운로드 받아서 js 폴더에 놓는다 -->

<script src="js/jquery-dateformat.js"></script>

<script src="js/underscore.js"></script>

<script src="js/backbone.js"></script>

<script src="js/ride.js"></script>


  - 브라우져 화면에서 MongoDB로 add 하기 : Backbone의 ride.js 에서 addRide 수정

var RidesView = Backbone.View.extend({

        el: $("#rides"),


        initialize: function(){

            this.collection = new Rides(rides);

            // 서버로 부터 데이터 가져오기 

            this.collection.fetch();

            this.render();

            // 컬렉션 add가 호출되면 renderRide를 trigger 한다 

            this.collection.on("add", this.renderRide, this);

            this.collection.on("remove", this.removeRide, this);

            // fetch()가 비동기적이기 때문에 Backbone이 reset을 호출하면 trigger 될 수 있도록 한다 

            this.collection.on("reset", this.render, this);

        },


        render: function(){

            var that = this;

            _.each(this.collection.models, function(item){

                that.renderRide(item);

            }, this);

        },


        renderRide: function(item){

            var rideView = new RideView({

                model: item

            });

            this.$el.append(rideView.render().el);

        },


        addRide: function(e){

            e.preventDefault();


            var formData = {};

            // jQuery의 each로 formData key=value 객체를 만듦

            $("#addRide").children("input").each(function (i, el) {

                if ($(el).val() !== "") {

                    formData[el.id] = $(el).val();

                }

            });


            // rides 배열에 저장

            rides.push(formData);

            // 컬렉션 객체에 저장

            // 서버로 저장하기 기존 add를 create 으로 바꾸면 된다 

            this.collection.create(formData); 

            //this.collection.add(new Ride(formData));

        }, 


  - 브라우져 결과 화면 : "평택 대회" 입력

   


  - MongoDB의 결과값 : 3개의 도큐먼트가 존재한다 

> db.rides.find().toArray();

[

{

"title" : "투어 드 코리아3",

"rider" : "윤영식",

"ridingDate" : ISODate("2012-06-01T00:00:00Z"),

"keywords" : "싸이클링 코리아 우승",

"_id" : ObjectId("5142dc4ae196a916e0000001"),

"__v" : 0

},

{

"title" : "대관령 힐크라이밍 대회",

"rider" : "윤도원",

"ridingDate" : ISODate("2013-07-01T00:00:00Z"),

"keywords" : "강원도 우승목표",

"_id" : ObjectId("5142dd8cba03b734e1000001"),

"__v" : 0

},

{

"title" : "평택 대회",

"rider" : "윤복자",

"ridingDate" : ISODate("2013-03-01T00:00:00Z"),

"keywords" : "고속도로 개통기념",

"_id" : ObjectId("5142de7351b4341ee2000001"),

"__v" : 0

}

]

>


  - 원문에 포함된 날짜 포함하기와 키워드배열로 만들기는 패스~~~ ^^;


** 전체 소스 코드 

riding.zip



<참조>

  - 원문 : Backbone.js Developing 번역글

  - Node.js & Express & Mongoose ToDo 예제

  - Handlebars 홈페이지

  - Tool : Advanced Rest Client

저작자 표시 비영리 변경 금지
신고
posted by peter yun 윤영식
2013.03.15 13:30 Backbone.js

Backbone.js 서점 샘플 예제를 사이클링 샘플로 변경하면서 직접 코딩해 보고 구조를 파악하자. 



1) index.html 파일 준비하기 

  - 이미지 파일 다운로드 하고 img 폴더에 넣는다 (100*152)

   


  - backbone.js, underscore.js, jquery.js 파일 다운로드 받아서 js 폴더에 넣는다 

   


  - index.html 파일을 루트에 생성한다


  - 브라우져 수행 점검 

   


  - css 폴더를 만들고 screen.css 파일을 생성한다 

css body { background-color: #eee; }

.bookContainer { border: 1px solid #aaa; width: 350px; height: 170px; background-color: #fff; float: left; margin: 5px; } .bookContainer img { float: left; margin: 10px; } .bookContainer ul { list-style-type: none; }



2) index.html 확장하기 

  - script 태그를 넣는다 

<script id="rideTemplate" type="text/template">

        <img src="<%= coverImage %>"/>

        <ul>

            <li><%= title %></li>

            <li><%= rider %></li>

            <li><%= ridingDate %></li>

            <li><%= keywords %></li>

        </ul>

    </script>

   Model의 명칭과 template의 <%= 명칭 %> 을 일치시켰다

   


  

3) ride.js 통해 Backbone 코딩하기 

  - js 폴더안에 ride.js파일을 생성하고 Model, View 클래스를 만든다 

(function ($) {

    // model 만들기

    var Ride = Backbone.Model.extend({

        defaults:{

            coverImage:"img/my_cycle.png",

            title:"2011년 대관령 대회",

            rider:"Yun YoungSik",

            ridingDate:"2011",

            keywords:"대관령 힐크라이밍 대회"

        }

    });


    // view 만들기

    var RideView = Backbone.View.extend({

        // el 변수에 html에 있는 DOM 레퍼런스를 만든다. $el은 DOM에 대한 jQuery 객체를 의미 한다  

        // html에 없는 DOM을 만들때는 tagName/className/id 등을 설정한다. 설정하지 않으면 기본 div 태그임

        // el 이란 무엇인가?

        tagName:"div",

        // screen.css 에서 사용할 css의 클래스이름 .rideContainer 

        className:"rideContainer",

        template:$("#rideTemplate").html(),


        render:function () {

            //tmpl은 JSON객체를 받아서 html을 반환하는 함수이다.

            var tmpl = _.template(this.template); 

            //jQuery html() 함수를 사용하기 위해 jQuery객체 $el을 쓴다.

            this.$el.html(tmpl(this.model.toJSON())); 

            return this;

        }

    });


})(jQuery);


  - View를 생성하고 Model를 할당한 후 render()를 호출하여 화면을 그린다 

(function ($) {

    // model 만들기

    var Ride = Backbone.Model.extend({

        defaults:{

            coverImage:"img/my_cycle.png",

            title:"2011년 대관령 대회",

            rider:"Yun YoungSik",

            ridingDate:"2011",

            keywords:"대관령 힐크라이밍 대회"

        }

    });


    // view 만들기

    var RideView = Backbone.View.extend({

        tagName:"div",

        className:"rideContainer",

        template:$("#rideTemplate").html(),


        render:function () {

        //tmpl은 JSON객체를 받아서 html을 반환하는 함수이다.

            var tmpl = _.template(this.template); 

            //this.el은 tagName에 정의된 것이다. jQuery html() 함수를 사용하기 위해서는 $el을 쓴다.

            this.$el.html(tmpl(this.model.toJSON())); 

            return this;

        }

    });


   // model, view 생성하여 view에 model 할당하기 

    var ride = new Ride({

        title:"Some title",

        rider:"Yun DoWon",

        ridingDate:"2011",

        keywords:"대관령 힐크라이밍 대회"

    });


    rideView = new RideView({

        model: ride

    });

    // 템플릿에 값을 맵핑한 DOM 을 최종적으로 넘김 

    $("#rides").html(rideView.render().el);

    

})(jQuery);


  - 브라우져 호출 결과화면 

    



4) Collection을 통해 목록 만들기 

 - Collection 클래스를 상속받아 Collection Model을 만들고 Collection을 제어할 수 있는 View도 만든다 

(function ($) {


    var Ride = Backbone.Model.extend({

        defaults:{

            coverImage:"img/my_cycle.png",

            title:"2011년 대관령 대회",

            rider:"Yun YoungSik",

            ridingDate:"2011",

            keywords:"대관령 힐크라이밍 대회"

        }

    });


    var RideView = Backbone.View.extend({

        tagName:"div",

        className:"rideContainer",

        template:$("#rideTemplate").html(),


        render:function () {

        //tmpl은 JSON객체를 받아서 html을 반환하는 함수이다.

            var tmpl = _.template(this.template); 

            //this.el은 tagName에 정의된 것이다. jQuery html() 함수를 사용하기 위해서는 $el을 쓴다.

            this.$el.html(tmpl(this.model.toJSON())); 

            return this;

        }

    });


    var ride = new Ride({

        title:"Some title",

        rider:"Yun DoWon",

        ridingDate:"2011",

        keywords:"대관령 힐크라이밍 대회"

    });


    var rideView = new RideView({

        model: ride

    });


    $("#rides").html(rideView.render().el);

    

    //////////////////////

    // rides 샘플 3개 생성

    var rides = [{title:"대관령 힐크라이밍 대회", rider:"Yun YoungSik", ridingDate:"2010", keywords:"대관령"},

        {title:"미시령 힐크라이밍 대회", rider:"Yun DoWon", ridingDate:"2011", keywords:"미시령"},

        {title:"투어 드 코리아", rider:"Yun YoungSik", ridingDate:"2012", keywords:"코리아"}];


    //////////////////////

    // Ride Collection 생성

    var Rides = Backbone.Collection.extend({

        model : Ride

    });


    //////////////////////

    // Collection View 생성

    var RidesView = Backbone.View.extend({

        el:$("#rides"),


        initialize:function(){

            this.collection = new Rides(rides);

            this.render();

        },


        // 컬렉션의 내역을 루핑을 돌고, 

        // each 메소드내에서서 함수 그자체가 this가 된다. 따라서 this 참조 안하게 that 을 설정한다 (블로깅)

        render: function(){

            var that = this;

            _.each(this.collection.models, function(item){

                that.renderRide(item);

            }, this);

        },


        // RideView 를 통해 개별적으로 렌더링한다 

        renderRide:function(item){

            var rideView = new RideView({

                model: item

            });

            this.$el.append(rideView.render().el);

        }

    });


    // new 를 하면  initialize() 가 자동 호출된다 

    var ridesView = new RidesView();


})(jQuery);


  - 호출한 결과 화면 : 기존 1개와 샘플 데이터 4개로 총 4개의 화면이 나옴 

   



5) 컬렉션에 모델을 추가하기 

  - 옷 신제품 발표 컬렉션에 옷입은 모델들을 추가하는 느낌이랄까 어감이 비슷하네요. ^^

  - 모델을 추가하기 위해서 index.html에 input tag 를 추가한다 

.. 중략 ..

<div id="rides">

    <!-- default 로 들어 있던 div 태그 제거 --> 

    <!--div class="rideContainer">

        <img src="img/my_cycle.png"/>

        <ul>

            <li>Title</li>

            <li>Rider</li>

            <li>Riding date</li>

            <li>Keywords</li>

        </ul>

    </div-->


    <!-- 새로운 카드를 넣을 수 있는 input tags --> 

    <div id="addRide">

        <label for="coverImage">CoverImage: </label><input id="coverImage" type="file" />

        <label for="title">Title: </label><input id="title" type="text" />

        <label for="rider">Rider: </label><input id="rider" type="text" />

        <label for="ridingDate">Riding date: </label><input id="ridingDate" type="text" />

        <label for="keywords">Keywords: </label><input id="keywords" type="text" />

        <button id="add">Add</button>

    </div>


    <!-- 하단의 template script 만 놓는다 --> 

    <script id="rideTemplate" type="text/template">

.. 중략 ..


  - screen.css 파일에 하기 내역을 추가한다 

css body { background-color: #eee; }


.rideContainer { border: 1px solid #aaa; width: 350px; height: 170px; background-color: #fff; float: left; margin: 5px; } .rideContainer img { float: left; margin: 10px; } .rideContainer ul { list-style-type: none; }


#addRide label {

    width:100px;

    margin-right:10px;

    text-align:right;

    line-height:25px;

}


#addRide label, #addRide input {

    display:block;

    margin-bottom:10px;

    float:left;

}


#addRide label[for="title"], #addRide label[for="ridingDate"] {

    clear:both;

}


#addRide button {

    display:block;

    margin:5px 20px 10px 10px;

    float: right;

    clear: both;

}


#addRide div {

    width: 550px;

}


#addRide div:after {

    content:"";

    display:block;

    height:0;

    visibility:hidden;

    clear:both;

    font-size:0;

    line-height:0;

}


  - ride.js 파일에서 RidesView 안의 renderRide 메소드 밑으로 addRide 메소드를 추가한다

// 테스트로 한개 넣었던 코드에 대해서 주석처리한다.

/*  var ride = new Ride({

        title:"No title",

        rider:"Unknown",

        ridingDate:"Unknown",

        keywords:"empty"

    });


    var rideView = new RideView({

        model: ride

    });


    $("#rides").html(rideView.render().el);  */

    

.. 중략 ..

        renderRide:function(item){

            var rideView = new RideView({

                model: item

            });

            this.$el.append(rideView.render().el);

        },


        addRide: function(e){

      e.preventDefault();


            var formData = {};

      // jQuery의 each로 formData key=value 객체를 만듦

             $("#addRide").children("input").each(function (i, el) {

                if ($(el).val() !== "") {

                    formData[el.id] = $(el).val();

                }

            });


            // rides 배열에 저장

            //rides.push(formData);

            // 컬렉션 객체에 저장 

            this.collection.add(new Ride(formData));

        }, 

        

        // add버튼 누를때 이벤트 발생하여 addRide 메소드 호출

        events:{

            "click #add": "addRide"

        }


    });


  - 컬렉션에 모델이 추가되는 add 메소드 호출시 이벤트 발생토록 함

var RidesView = Backbone.View.extend({

        el:$("#rides"),


        initialize:function(){

            this.collection = new Rides(rides);

            this.render();


// initailize 초기화일 때 자동으로 trigger 될 수 있도록 설정을 합니다 

            this.collection.on("add", this.renderRide, this);

        },


  - 실행하기 

$ static 

serving "." at http://127.0.0.1:8080

11:16:58 [200]: /

11:16:58 [200]: /css/screen.css

11:16:58 [200]: /js/ride.js

11:16:58 [200]: /js/underscore.js

11:16:58 [200]: /js/backbone.js

11:16:58 [200]: /img/my_cycle.png

11:16:58 [200]: /js/jquery.js

11:16:58 [404]: /favicon.ico


    + http://localhost:8080 호출 한 경우

   

    + 값을 입력하고 "Add" 클릭하였을 때 (평택 대회)

   



6) 모델 삭제하기 

  - index.html안에 삭제 버튼을 넣는다 

 <script id="rideTemplate" type="text/template">

        <img src="<%= coverImage %>"/>

        <ul>

            <li><%= title %></li>

            <li><%= rider %></li>

            <li><%= ridingDate %></li>

            <li><%= keywords %></li>

        </ul>

        <button class="delete">Delete</button>

    </script>


  - button에 대한 screen.css 를 조정한다 

.rideContainer ul {

    list-style-type: none;

    margin-bottom: 0;

}


.rideContainer button {

    float:right;

    margin: 10px;

}


  - 개별 모델에 delete button이 놓인다

   


  - 삭제 로직을 RideView 에 코딩한다 : 삭제 메소드 -> 이벤트 등록

     var RideView = Backbone.View.extend({

        tagName:"div",

        className:"rideContainer",

        template:$("#rideTemplate").html(),


        render:function () {

         //tmpl은 JSON객체를 받아서 html을 반환하는 함수이다.

            var tmpl = _.template(this.template); 

            //this.el은 tagName에 정의된 것이다. jQuery html() 함수를 사용하기 위해서는 $el을 쓴다.

            this.$el.html(tmpl(this.model.toJSON())); 

            return this;

        }, 


        events: {

            "click .delete": "deleteRide"

        },


        deleteRide:function () {

            //모델을 삭제한다.

            this.model.destroy();


            //뷰를 삭제한다.

            this.remove();

        }

    });



7) 컬렉션 모델 삭제하기

  - rides 배열에는 아직 그대로 데이터가 존재한다. 이를 삭제하기 위하여 먼저 remove 이벤트의 trigger를 RidesView에 등록한다

var RidesView = Backbone.View.extend({

        el: $("#rides"),


        initialize: function(){

            this.collection = new Rides(rides);

            this.render();

            // 컬렉션 add가 호출되면 renderRide를 trigger 한다 

            this.collection.on("add", this.renderRide, this);

            this.collection.on("remove", this.removeRide, this);

        },


        render: function(){

            var that = this;

            _.each(this.collection.models, function(item){

                that.renderRide(item);

            }, this);

        },


        renderRide: function(item){

            var rideView = new RideView({

                model: item

            });

            this.$el.append(rideView.render().el);

        },


        addRide: function(e){

            e.preventDefault();


            var formData = {};

            // jQuery의 each로 formData key=value 객체를 만듦

            $("#addRide").children("input").each(function (i, el) {

                if ($(el).val() !== "") {

                    formData[el.id] = $(el).val();

                }

            });


            // rides 배열에 저장

            rides.push(formData);

            // 컬렉션 객체에 저장 

            this.collection.add(new Ride(formData));

        }, 


        // 삭제된 모델을 인자로 자동 넣어준다 

        removeRide: function(removedRide){

            // attributes는 Model의 hash key=value object 이다 

            var removedRideData = removedRide.attributes;


            _.each(removedRideData, function(val, key){

                if(removedRideData[key] === removedRide.defaults[key]){

                    console.log(">> 1 : " + removedRideData[key]);

                    delete removedRideData[key];

                }

            });


            _.each(rides, function(ride){

                if(_.isEqual(ride, removedRideData)){

                    console.log(">> 2 : " + ride);

                    rides.splice(_.indexOf(rides, ride), 1);

                }

            });

        },

        

        // add버튼 누를때 이벤트 발생하여 addRide 메소드 호출

        events:{

            "click #add": "addRide"

        }

    });


  - 삭제버튼을 클릭하면 삭제가 잘 된다 



* 지금까지의 소스 

riding.zip



<참조>

  - 원문 : Backbone.js Developing 번역글

저작자 표시 비영리 변경 금지
신고
posted by peter yun 윤영식
prev 1 next