개발일지

Backbone.js + Sync

• javascript

Backbone.js 에서 Sync기능 사용법

Backbone.js의 Sync기능은 기본적으로 Restful한 서버에서 동작합니다.
이 기능을 실습해 보기 위해서 실제로 서버를 구현하는 것은 그것대로 좋은 경험이겠지만
정작 Sync기능보다 서버를 구현하기 위한 학습시간이 더 길어지곤 했습니다.
그래서 이틀 걸려(?) 다음의 라이브러리를 만들었습니다!(차라리 서버를 만들지 그랬어;;)
static 웹 페이지에서 동작하는 간단한 stub서버
(Sinon.js도 잠시 고려했었으나, Url을 판별하기 위해서 정규표현식을 사용해야 하고, $.ajax에 대응하는 dataType이 html으로 한정되기에 사용하지 않기로 결정했습니다.)


BackBone.js의 Sync기능은 기본적으로 다음과 같은 HTTP메소드를 사용하는 서버와 연동됩니다.
update: PUT
delete: DELETE
create: POST
select: GET

  1. 우선 가상 서버에 GET, PUSH, DELETE, POST메소드를 작성해 줍시다.
    이곳의 코드를 사용하세요.

  2. 가상 서버와 연동할 Backbone.Collection을 구현합니다.

//1. 모델 선언
var User = Backbone.Model.extend({
    //모델 생성시의 초기값 설정
    defaults: {
        id:1,
        name:'익명'
    },
    urlRoot: '/users',
    idAttribute:'id',
});

//2. 컬렉션 선언
var UserList = Backbone.Collection.extend({
    model: User,
    url: '/users',
    initialize: function(){
        this.on('add', function(model, collection){
            console.log('컬렉션의 add이벤트 핸들러 반응함');
        });

        this.on('remove', function(model, collection){
            console.log('컬렉션의 remove이벤트 핸들러 반응함');
        });

        //모델 내부 name프로퍼티의 change이벤트핸들러
        this.on('change:name', function(model, value){
            console.log('컬렉션의 change이벤트 핸들러 반응함');
        });
    }
});

//3. 컬렉션 생성
var userList = new UserList();
userList.fetch();

정상적으로 동작하는지 개발자 도구를 통해 확인해 봅니다.

//컬렉션 생성
var userList = new UserList();
//전체 리스트를 Read
userList.fetch();
//레코드 1개를 Read
userList.at(0).fetch();
//레코드 1개를 Create
userList.create({id:'999',name:'구구구'});
//레코드 1개를 Delete
userList.at(0).remove();
//레코드 1개를 Update
userList.at(0).set({name:'변경된 이름'}).save();

그런데 분명 Create 명령을 내렸는데, Update를 합니다..!

//레코드 1개를 Create
userList.create({id:'999',name:'구구구'});

그 이유는 모델 생성 초기값에 id속성을 넣었기 때문이었습니다.

//http://blog.jonhibbard.com/2014/10/backbonejs-collection-create-gotcha-put-request-sent-instead-of-post/
var User = Backbone.Model.extend({
    //모델 생성시의 초기값 설정
    defaults: {
        //id:1, <=모델 생성 초기값에 id속성을 넣으면 Create명령 대신, Update명령을 실행하니 주의할것!
        name:'익명'
    },
    urlRoot: '/users',
    idAttribute:'id',
});
  1. Backbone.Sync 메소드 테스트
    다음과 같이 전역 Sync 메소드를 구현하면 원래의 Sync기능을 오버라이드합니다.
    즉, Restful하지 않은 서버와 통신해야 할 때, 이 함수를 구현하면 됩니다.
Backbone.sync = function(method, model){
    console.info('전역 Sync메소드 호출[s]');
    console.info(method + ':' + JSON.stringify(model.toJSON(),'',4));
    console.info('전역 Sync메소드 호출[e]');
};
  1. Backbone.Model.Sync ,Backbone.Collection.Sync 메소드 테스트
    이들 모두 오버라이드 가능한 sync메소드가 있습니다.
    이 부분을 오버라이드 하면 Restful하지 않은 서버와 통신할 수 있게 됩니다.
var User = Backbone.Model.extend({
    //모델 생성시의 초기값 설정
    defaults: {
        id:1,
        name:'익명'
    },
    urlRoot: '/users',
    idAttribute:'id',
    //이 부분을 오버라이드 하면 Restful하지 않은 서버와 통신할 수 있게 됩니다.
    sync:function(method, model, options){
         console.info('모델의 Sync메소드 호출[s]');
         console.info(method + ':' + JSON.stringify(model.toJSON(),'',4));
         console.info('모델의 Sync메소드 호출[e]');
    },
});

결론
1. Backbone.sync, Backbone.Model.Sync, Backbone.Collection.Sync 함수를 구현해 주면
Restful하지 않은 서버를 대상으로도 Sync기능을 활용할 수 있다.
2. Backbone.Model과 Backbone.Collection의 defaults 프로퍼티에 id 어트리뷰트를 삽입하면
Sync의 create명령이 update명령으로 오동작할 수 있다.

comments powered by Disqus