Разные функции KnockoutJS

Предположим, емеются такие данные

var JSONdataFromServer = '[{"name":"Peach","category":"Fruits","price":1},{"name":"Plum","category":"Fruits","price":0.75},{"name":"Donut","category":"Bread","price":1.5},{"name":"Milk","category":"Dairy","price":4.50}]';

В Knockout имеется функция ko.utils.parseJson

var dataFromServer = ko.utils.parseJson(JSONdataFromServer);

Допустим нам нужно создать observable-перменную, которая считает сумму всех айтемов. В Knockout есть функция ko.utils.arrayForEach

viewModel.total = ko.computed(function() {
    var total = 0;
    ko.utils.arrayForEach(this.items(), function(item) {
        var value = parseFloat(item.price);
        if (!isNaN(value)) {
            total += value;
        }
    });
    return total.toFixed(2);
}, viewModel);

Если нам нужно отфильтровать объект по имени, то можно создать observable элемент, который возвращает отфильтрованные элементы

Для этого есть функция ko.utils.arrayFilter

// берет данные с помощью текстового фильтра
viewModel.filteredItems = ko.computed(function() {
    var filter = this.filter().toLowerCase();
    if (!filter) {
        return this.items();
    } else {
        return ko.utils.arrayFilter(this.items(), function(item) {
            return ko.utils.stringStartsWith(item.name().toLowerCase(), filter);
        });
    }
}, viewModel);

Иногда нужно брать первый элемент из списка. Для этого есть функция ko.utils.arrayFirst

// первый элемент, совпавший по имени
viewModel.firstMatch = ko.computed(function() {
    var search = this.search().toLowerCase();
    if (!search) {
        return null;
    } else {
        return ko.utils.arrayFirst(this.filteredItems(), function(item) {
            return ko.utils.stringStartsWith(item.name().toLowerCase(), search);
        });
    }
}, viewModel);

Для фильтрации массива используется функция ko.utils.arrayMap

// вернет список категорий
viewModel.justCategories = ko.computed(function() {
    var categories = ko.utils.arrayMap(this.items(), function(item) {
        return item.category();
    });
    return categories.sort();
}, viewModel);

Если нужно получить уникальные категории из нашего массива, то можно воспользоваться функцией ko.utils.arrayGetDistinctValues

// вернет список уникальных категорий
viewModel.uniqueCategories = ko.dependentObservable(function() {
    return ko.utils.arrayGetDistinctValues(viewModel.justCategories()).sort();
}, viewModel);

Сравнение двух массивов. Допустим, нам нужно получить массив категорий, которые отсутсвуют в наших данных. В Knockout есть функция ko.utils.compareArrays

// найти отсутствующие категории
viewModel.missingCategories = ko.dependentObservable(function() {
    //find out the categories that are missing from uniqueNames
    var differences = ko.utils.compareArrays(viewModel.categories, viewModel.uniqueCategories());
    //return a flat list of differences
    var results = [];
    ko.utils.arrayForEach(differences, function(difference) {
        if (difference.status === "deleted") {
            results.push(difference.value);
        }
    });
    return results;
}, viewModel)

 

Для удаления свойств из нашего массива можно воспользоваться фукнцией ko.toJS: преобразовать observable в обычные объекты, а затем ko.utils.arrayMap

var items = ko.toJS(this.items);
var mappedItems = ko.utils.arrayMap(items, function(item) {
    delete item.priceWithTax;
    return item;
});