Scriptify.ru

Данное руководство предназначено для понятия основ работы с коллекциями Backbone.

Коллекции представляют собой множества моделей и создаются путем расширения класса Backbone.Collection. При создании коллекции требуется также задать свойство, определяющее тип модели, которую будет содержать ваша коллекция:

    var todo = Backbone.Model.extend({
        defaults: {
            title: '',
            completed: false
        }
    });

    var todoCollections = Backbone.Collection.extend({
        model: todo
    });

Добавление и удаление моделей

После создания коллекции можно добавлять и удалять модели с помощью методов add() и remove(). В данном примере мы добавим две модели в коллекцию, а затем удалим одну из них:

    var todo = Backbone.Model.extend({});

    var todo1 = new todo({
        title: 'Задача 1',
        completed: false
    });

    var todoCollections = Backbone.Collection.extend({
        model: todo
    });    
    // создание экземпляра коллекции    
    var todos = new todoCollections();
    // Добавление модели
    todos.add([todo1]);
    // добавить модель можно и без создания ее экземпляра 
    todos.add({title: 'Задача 2', completed: false});

    console.log('Количество элементов коллекции: ' + todos.length);
    // В консоль:
    // Количество элементов коллекции: 2

    // удаление модели  
    todos.remove(todo1);
    console.log('Количество элементов коллекции: ' + todos.length);
    // В консоль:
    // Количество элементов коллекции: 1

Слияние моделей

Если у моделей в коллекции есть одинаковые атрибуты, их можно объединить при помощи параметра merge. Если указан merge:true, то атрибуты одинаковых моделей добавляются к существующим объектам. Если merge:false, то атрибуты игнорируются.

    var items = new Backbone.Collection;
    items.add([{id: 1, name: 'dog'}]);
    items.add([{id: 1, name: 'bear', age: 3}], {merge: true});
    console.log( 'Результат слияния моделей с {merge: true}: ' + JSON.stringify(items.toJSON()) );
    // В консоль:
    // Результат слияния моделей с {merge: true}: [{"id":1,"name":"bear","age":3}]

    var items = new Backbone.Collection;
    items.add([{id: 1, name: 'dog'}]);
    items.add([{id: 1, name: 'bear', age: 3}], {merge: false});
    console.log( 'Результат слияния моделей с {merge: false}: ' + JSON.stringify(items.toJSON()) ); 
    // В консоль:
    // Результат слияния моделей с {merge: false}: [{"id":1,"name":"dog"}]

Прослушивание событий

По аналогии с моделями можно прослушивать события в коллекциях и обрабатывать их. В данном примере мы добавим обработчик события add, который будет выполняться каждый раз при добавлении новой модели.

    var todolist = new Backbone.Collection;

    // добавляем обработчик события add    
    todolist.on('add', function(todo) {
        console.log('Я должен ' + todo.get('title') + '. Задача выполнена? ' + (todo.get('completed') ? 'Да' : 'Нет' ))
    });

    // добавляем модели в коллекцию    
    todolist.add([
        {title: 'изучить javascript', completed: true },
        {title: 'изучить backbone', completed: false},
    ]);

    // В консоль:
    // Я должен изучить javascript. Задача выполнена? Да
    // Я должен изучить backbone. Задача выполнена? Нет

Считывание моделей

Считывать модели из коллекции можно различными способами. Самый простой способ - это использование метода get(), который принимает единственный параметр id.

    var todolist = new Backbone.Collection([
        {title: 'изучить javascript', completed: true, id: 1 },
        {title: 'изучить backbone', completed: false, id: 2},
    ]);
    // доступ к модели по id
    var todo1 = todolist.get(1);
    console.log( 'Получение модели с id=1: ' + JSON.stringify(todo1));
    // В консоль:
    // Получение модели с id=1: {"title":"изучить javascript","completed":true,"id":1}

Перезапись и обновление коллекций

Метод Collection.set() позволяет обновлять коллекцию с помощью операций добавления, удаления и изменения моделей. Для замены всей коллекции воспользуйтесь методом Collection.reset().

    var todolist = new Backbone.Collection([
        {title: 'изучить javascript', completed: true, id: 1},
        {title: 'изучить backbone', completed: false, id: 2},
    ]);

    // обновление коллекции
     todolist.set([
        {title: 'изучить javascript', completed: true, id: 1},
        {title: 'изучить backbone', completed: true, id: 3},
        {title: 'изучить marionette', completed: false, id: 4},
    ]);    
    console.log( 'Произошло обновление коллекции: ' + JSON.stringify(todolist));
    // В консоль:
    // Произошло обновление коллекции: [{"title":"изучить javascript","completed":true,"id":1},{"title":"изучить backbone","completed":true,"id":3},{"title":"изучить marionette","completed":false,"id":4}]

    // замена всей коллекции
    todolist.reset([
        {title: 'изучить react', completed: false}
    ]);
    console.log( 'Произошла замена коллекции: ' + JSON.stringify(todolist));
    // В консоль:
    // Произошла замена коллекции: [{"title":"изучить react","completed":false}]

Вспомогательные методы библиотеки Underscore

Backbone позволяет применять функции Underscore.js к коллекциям.

forEach() выполняет определенные действия для каждого элемента коллекции:

    var todos = new Backbone.Collection([
        {title: 'javascript', completed: true, id: 1},
        {title: 'backbone', completed: true, id: 2},
        {title: 'marionette', completed: false, id: 3}
    ]);

    todos.forEach(function(model){
        console.log( 'Перебор коллекции методом forEach(): ' + model.get('title'));
    });
    // В консоль:
    // Перебор коллекции методом forEach(): javascript
    // Перебор коллекции методом forEach(): backbone
    // Перебор коллекции методом forEach(): marionette

sortBy() позволяет сортировать элементы в указанном порядке:

    var todos = new Backbone.Collection([
        {title: 'javascript', completed: true, id: 1},
        {title: 'backbone', completed: true, id: 2},
        {title: 'marionette', completed: false, id: 3}
    ]);

    var sorted = todos.sortBy(function(todo) {
       return todo.get('title').toLowerCase(); 
    });

    console.log( 'Сортировка коллекции по атрибуту title: ' + JSON.stringify(sorted));
    // В консоль:
    // Сортировка коллекции по атрибуту title: [{"title":"backbone","completed":true,"id":2},{"title":"javascript","completed":true,"id":1},{"title":"marionette","completed":false,"id":3}]

map() создает новую коллекцию из списка значений с помощью функции преобразования:

    var todos = new Backbone.Collection([
        {title: 'javascript', completed: true, id: 1},
        {title: 'backbone', completed: true, id: 2},
        {title: 'marionette', completed: false, id: 3}
    ]);

    var count = 1;
    var mapped = todos.map(function(model) {
        return count++ + '. ' + model.get('title');
    });

    console.log( 'Создание новой коллекции через функцию преобразования: ' + JSON.stringify(mapped));
    // В консоль:
    // Создание новой коллекции через функцию преобразования: ["1. javascript","2. backbone","3. marionette"]

min() / max() считывает элемент с максимальным или минимальным значением атрибута

    var todos = new Backbone.Collection([
        {title: 'javascript', completed: true, id: 1},
        {title: 'backbone', completed: true, id: 2},
        {title: 'marionette', completed: false, id: 3}
    ]);

    var todomax = todos.max(function(model){
        return model.id;
    }).id;   
    var todomin = todos.min(function(model){
        return model.id;
    }).id;

    console.log( 'Максимальное значение id: ' + JSON.stringify(todomax));   
    console.log( 'Минимальное значение id: ' + JSON.stringify(todomin));
    // В консоль:
    // Максимальное значение id: 3
    // Минимальное значение id: 1  

pluck() извлекает значения одного или всех атрибутов

    var todos = new Backbone.Collection;

    todos.add([
        {title: 'javascript', completed: true, id: 1},
        {title: 'backbone', completed: true, id: 2},
        {title: 'marionette', completed: false, id: 3}
    ]);    

    var plucks = todos.pluck('title');    
    console.log(JSON.stringify(plucks));
    // В консоль:
    // ["javascript","backbone","marionette"]

indexOf() возвращает индекс элемента внутри коллекции

    var todoModel = Backbone.Model.extend({});  
    var todo1 = new todoModel({id: 1, title: 'javascript', completed: true});
    var todo2 = new todoModel({id: 2, title: 'backbone',   completed: false});          
    var todosCollection = new Backbone.Collection([todo1, todo2]);  
    console.log('Индекс указанного элемента равен ' + todosCollection.indexOf(todo1));
    // В консоль:
    // Индекс указанного элемента равен 0

any() проверяет, содержит ли коллекция хотя бы одно указанное значение

    var todos = new Backbone.Collection;

    todos.add([
        {title: 'javascript', completed: true, id: 1},
        {title: 'backbone', completed: true, id: 2},
        {title: 'marionette', completed: false, id: 3}
    ]); 

    var anything = todos.any(function(model) {
        return model.id === 2;  
    });
    console.log(JSON.stringify(anything) ? 'Указанное значение содержится в коллекции' : 'Указанное значение не содержится в коллекции' );
    // В консоль:
    // Указанное значение содержится в коллекции

groupBy() позволяет группировать элементы по указанным атрибутам

    var todos = new Backbone.Collection;

    todos.add([
        {title: 'javascript', completed: true, id: 1},
        {title: 'backbone', completed: true, id: 2},
        {title: 'marionette', completed: false, id: 3}
    ]);     

    var groupped = todos.groupBy('completed');
    var completed = new Backbone.Collection(groupped[true]);
    console.log('Список выполненных задач ' + JSON.stringify(completed));
    // В консоль:
    // [{"title":"javascript","completed":true,"id":1},{"title":"backbone","completed":true,"id":2}]

filter() позволяет фильтровать элементы по указанным условиям

    var todos = new Backbone.Collection([
        {name: 'Вася', age: 25},
        {name: 'Петя', age: 27},
        {name: 'Саня', age: 26}
    ]);

    var filteredCollection = todos.filter(function(item) {
        return item.get('age') > 25
    });

    console.log(JSON.stringify(filteredCollection));
    // В консоль:
    // [{"name":"Петя","age":27},{"name":"Саня","age":26}]

Указанные методы можно объединять в цепочки. Для этого необходимо использовать метод chain(). В примере ниже отфильтруем пользователей с возрастом более 25 лет и получим их имена:

    var todos = new Backbone.Collection([
        {name: 'Вася', age: 25},
        {name: 'Петя', age: 27},
        {name: 'Саня', age: 26}
    ]);    

    var filteredNames = todos
    .chain()
    .filter(function(item) { return item.get('age') > 25; })
    .map(function(item) { return item.get('name'); })
    .value();

    console.log(filteredNames);
    // В консоль:
    // ["Петя", "Саня"]

Содержание статьи