반응형

들어가며

설명

  • BackboneJS는 클라이언트 사이드 웹애플리케이션 개발에 MVC 패턴을 적용하게 해주는 프레임워크 중 하나이다.
  • Model, Collection, View의 세 가지 요소를 활용하여 웹 애플리케이션을 쉽게 개발할 수 있도록 해준다.
  • jquery, underscore를 의존한다.

기본 코드

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Backbone.js</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.1/underscore.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.4.0/backbone-min.js"></script>
<script>
    const User = Backbone.Model.extend({
        initialize: function () {
            console.log('initial');
        },
        defaults: {
            name: '',
            age: 0,
        }
    });

    const user = new User({
        name: 'john',
        age: 25
    });
</script>
</body>
</html>

Model

Basic

const User = Backbone.Model.extend({
    initialize: function () {
        console.log('initial');
    },
    defaults: {
        name: '',
        age: 0,
    }
});

const user = new User({
    name: 'john',
    age: 25
});

console.log(user.toJSON());
console.log(user.get('name'), user.get('age'));
console.log(user.has('name'));

user.unset('name');
console.log(user.get('name'), user.get('age'));

user.set('name', 'tom');
console.log(user.get('name'), user.get('age'));

user.clear();
console.log(user.get('name'), user.get('age'));

Validation

const User = Backbone.Model.extend({
    validate: function (attrs) {
        if (!attrs.name) {
            return "name is required";
        }

        return undefined;
    }
});

const user = new User();

console.log(user.isValid()); // false
console.log(user.validationError); // name is required

user.set('name', 'john');

console.log(user.isValid()); // true
console.log(user.validationError); // null

Inheritance

const Animal = Backbone.Model.extend({
    walk: function () {
        console.log('Animal walking');
    }
});

const Dog = Animal.extend({
    walk: function () {
        Animal.prototype.walk.apply(this);
        console.log('Dog walking');
    }
});

const animal = new Animal();
const dog = new Dog();

animal.walk(); // Animal walking
dog.walk(); // Animal walking\nDog walking

With API

const User = Backbone.Model.extend({
    urlRoot: '/api/users',
    idAttribute: 'userSeq'
});

function getUser() {
    const user = new User({userSeq: 1});

    // GET /api/users/1
    user.fetch({
        success: function (context, model, resp, options) {
            console.log('success', context, model, resp, options);
        },
        error: function (context, model, resp) {
            console.error('error', context, model, resp);
        },
    });
}

function addUser() {
    const user = new User({name: 'john'});

    // POST /api/users
    user.save();
}

function updateUser() {
    const user = new User({userSeq: 1, name: 'john'});

    // PUT /api/users/1
    user.save();
}

function deleteUser() {
    const user = new User({userSeq: 1});

    // DELETE /api/users/1
    user.destroy();
}

Collection

Basic

const User = Backbone.Model.extend();

const Users = Backbone.Collection.extend({
    model: User,
});

const users = new Users([
    new User({name: 'john'}),
    new User({name: 'tom'}),
]);
console.log(users.length, users.at(0).get('name')); // 2 "john"

users.remove(users.at(0));
console.log(users.length, users.at(0).get('name')); // 1 "tom"

users.add(new User({name: 'jane'}));
console.log(users.length, users.at(users.length - 1).get('name')); // 2 "jane"

With API

const User = Backbone.Model.extend();

const Users = Backbone.Collection.extend({
    model: User,
    url: '/api/users'
});

function getUsers() {
    const users = new Users();

    // GET /api/users?page=1
    users.fetch({
        data: {
            page: 1,
        },
        success: function (context, model, resp, options) {
            console.log('success', context, model, resp, options);
        },
        error: function (context, model, resp) {
            console.error('error', context, model, resp);
        },
    });
}

View

Render View

function render1() {
    const UserView = Backbone.View.extend({
        render: function () {
            this.$el.html('Hello World');
            return this;
        }
    });

    const userView = new UserView({el: '#container'});
    userView.render();
}

function render2() {
    const UserView = Backbone.View.extend({
        tagName: 'span',
        className: 'user',
        id: 'user-1',
        attributes: {
            'data-user-seq': 1
        },
        render: function () {
            this.$el.html('Hello World');
            return this;
        }
    });

    const userView = new UserView();
    userView.render();

    $('#container').html(userView.$el);
}

Passing Data to Views

function renderUserView() {
    const User = Backbone.Model.extend();

    const UserView = Backbone.View.extend({
        render: function () {
            this.$el.html(this.model.get('name'));
            return this;
        }
    });

    const user = new User({name: 'john'});

    const userView = new UserView({el: '#container', model: user});
    userView.render();
}

function renderUsersView() {
    const User = Backbone.Model.extend();

    const Users = Backbone.Collection.extend({
        model: User,
    });

    const UserView = Backbone.View.extend({
        tagName: 'li',
        render: function () {
            this.$el.html(this.model.get('name'));
            return this;
        }
    });

    const UsersView = Backbone.View.extend({
        render: function () {
            const self = this;

            self.model.each(function (user) {
                const userView = new UserView({model: user});
                self.$el.append(userView.render().$el);
            });
        }
    });

    const users = new Users([
        new User({name: 'john'}),
        new User({name: 'tom'}),
    ]);

    const usersView = new UsersView({el: '#container', model: users});
    usersView.render();
}

Handling the DOM Events

const User = Backbone.Model.extend();

const UserView = Backbone.View.extend({
    events: {
        'click': 'onClick',
        'click .click2': 'onClick2',
    },
    onClick: function () {
        console.log('onClick');
    },
    onClick2: function (e) {
        e.stopPropagation();
        console.log('onClick2');
    },
    render: function () {
        this.$el.html(this.model.get('name') + '<button>click1</button><button class="click2">click2</button>');
        return this;
    }
});

const user = new User({name: 'john'});

const userView = new UserView({el: '#container', model: user});
userView.render();

Handling the Model Events

const User = Backbone.Model.extend();

const UserView = Backbone.View.extend({
    initialize: function () {
        this.model.on('change', this.render, this);
    },
    render: function () {
        const name = this.model.get('name');
        const count = this.model.get('count');
        this.$el.html(`name : ${name}, count : ${count}`);
        return this;
    }
});

const user = new User({name: 'john', count: 0});

const userView = new UserView({el: '#container', model: user});
userView.render();

function increaseCount() {
    user.set('count', user.get('count') + 1);
}

Templating

<script id="userTemplate" type="text/html">
    <%= name %>
    <button>click</button>
    <% if (age > 30) { %>
    <span>old</span>
    <% } else { %>
    <span>young</span>
    <% } %>
</script>
const User = Backbone.Model.extend();

const UserView = Backbone.View.extend({
    render: function () {
        const template = _.template($('#userTemplate').html());
        const html = template(this.model.toJSON());
        this.$el.html(html);
        return this;
    }
});

const user = new User({name: 'john', age: 30});

const userView = new UserView({el: '#container', model: user});
userView.render();

참고

반응형

'Development > JS' 카테고리의 다른 글

[Javascript] remark, rehype  (1) 2021.01.07
[Javascript] Selection & Range  (0) 2021.01.05

+ Recent posts