Я пытаюсь создать одностраничное приложение (с Knockout.js - его необходимо использовать), которое имитирует страницу товаров в интернет-магазине. Вот как это выглядит (для лучшего понимания):
главная страница
Я использую require.js, knockout.js и underscore.js для фильтрации товаров по цене. Проблема в том, что иногда я получаю сообщение об ошибке, что _.filter не является функцией. Вот мой файл ViewModel для боковой панели:
define(
['jquery', 'underscore', 'knockout', 'core/get_product_list', 'core/read_set_data', 'text!view-model/sidebar/sidebar.tmpl'],
function ($, _, ko, getProductList, ReadSetData, sidebarTemplate) {
var SidebarViewModel = function (options) {
//Variables
var self = this;
self.sidebarElement = options.sidebarElement;
self.currentProductsPerPage = ReadSetData.currentProductsPerPage;
self.pageNumber = ReadSetData.pageNumber;
self.items = ReadSetData.items();
self.itemsTotal = ko.computed(function () {
return self.items.length;
});
self.filterPrice = ko.observableArray();
//Applying template
self.sidebarElement.html(sidebarTemplate);
//Filtering by price using Underscore
self.applyPriceFilter = ko.computed(function(){
if (self.filterPrice().length !== 0) {
var minValue, maxValue;
$.each(self.filterPrice(), function() {
var min = Number(this.split('-')[0]),
max = Number(this.split('-')[1]);
if (!minValue && !maxValue) {
minValue = min;
maxValue = max;
}
if (minValue > min) minValue = min;
if (maxValue < max) maxValue = max;
});
var filterItems = _.filter(self.items, function(item) {
return (item.price() > minValue && item.price() < maxValue);
});
ReadSetData.pageNumber(0);
ReadSetData.items(filterItems);
}
else
{
ReadSetData.pageNumber(0);
ReadSetData.items(self.items);
}
});
};
return SidebarViewModel;
});
Это фильтрация по цене, как и ожидалось, но если я обновлю страницу несколько раз - я получаю эту ошибку:
ошибка изображения
Если я обновлю страницу снова, эта ошибка исчезнет, и фильтрация снова будет работать нормально. Кажется, что underscore.js не загружается, и это является причиной ошибки (как я думаю).
Вот мой require.config:
require.config({
paths: {
text: '../libs/text/text',
jquery: '../libs/jquery/jquery-min',
popper: '../libs/popper/popper-min',
underscore: '../libs/underscore/underscore',
knockout: '../libs/knockout/knockout',
bootstrap: '../libs/bootstrap-grid/bootstrap',
material_design: '../libs/material-design/mdb'
},
shim: {
jquery: {
exports: '$'
},
underscore: {
exports: '_'
},
material_design: {
deps: ['jquery']
}
}
});
require(['jquery', 'popper', 'bootstrap', 'knockout', 'material_design', 'main'], function(
$,
popper,
bootstrap,
ko,
Material_design,
MainViewModel
) {
var mainContent = $('#main'); //keep a reference to the root element
// ---------------------------------------------
// Applying bind of the MainViewModel
// ---------------------------------------------
ko.applyBindings(
new MainViewModel({
element: mainContent
}),
mainContent[0]
);
});
Что я делаю не так? Может я что-то написал не в том порядке? Или есть идеи, что может быть не так? Спасибо!