Arr.js — это «класс», унаследованный от стандартного Array
. Отличительными особенностями являются: наличие события change
для отслеживания любых изменений в массиве, и методы insert()
, update()
, remove()
, set()
, get()
для упрощенной работы с массивом. Доступны все «родные» методы стандартного Array
.
var fruits = new Arr('apple', 'orange', 'pineapple');
fruits.on('change', function(event) {
alert('I changed fruits: ' + fruits.join(', '));
});
fruits.push('banana');
var fruits = new Arr('apple', 'orange', 'pineapple');
fruits.get(0);
// apple
fruits.get(10, 'lime'); // trying to get undefined element - return defaultValue
// lime
fruits.get(20); // trying to get undefined element
// null
fruits.set(1, 'nut');
// ['nut', 'orange', 'pineapple']
fruits.insert(['lime', 'banana', 'kivi']);
// ['nut', 'orange', 'pineapple', 'lime', 'banana', 'kivi']
fruits.remove(function(item, index) {
if (item.indexOf('apple') !== -1) { // remove only items where word "apple" is founded
return true;
}
});
// ['nut', 'orange', 'lime', 'banana', 'kivi']
fruits.update(function(item, index) {
if (item.indexOf('nut') !== -1) { // update "nut" to "apple"
return 'apple';
}
});
// ['apple', 'orange', 'lime', 'banana', 'kivi']
Зачем событие change и как с ними работать
Наличие события позволяет сделать:
- подобие FRP: когда изменение одних данных должно повлечь за собой изменение других данных и так далее
- отложенный рендеринг: что то изменилось в массиве — обновили HTML (ala angular)
- автоматическое сохранение данных на сервер при любых изменениях
Поддерживается одно событие — change
.
var fruits = new Arr('apple', 'orange', 'pineapple');
fruits.on('change', function(event) { // handler
console.log(event);
});
fruits.push('banana');
// { "type": "insert", "items": ["banana"] }
fruits.remove(function(item) { return item == 'banana'; });
// { "type": "remove", "items": ['banana"] }
Понять что произошло в массиве можно по передаваемому в handler
объекту, event
. Свойства объекта event
: type
может принимать значения: insert
, update
, remove
. Свойство items
позволяет узнать какие элементы массива были затронуты.
Наглядный пример
// Массив в котором планируем хранить данные о погоде
var weatherList = new Arr;
// При изменении в массиве - перересовываем список
weatherList.on('change', function() {
var el = $('#weather');
var celsius, maxCelsius, minCelsius, weather;
el.html('');
weatherList.forEach(function(item) {
celsius = Math.floor(item.main.temp - 273);
maxCelsius = Math.floor(item.main.temp_max - 273);
minCelsius = Math.floor(item.main.temp_min - 273);
weather = item.weather.pop().main;
el.append('<li><b>' + item.name + '</b> ' + ' ' + celsius + ' (max: ' + maxCelsius + ', min: ' + minCelsius + ') ' + weather + '</li>');
});
});
// Загрузка погоды из сервиса, обновление массива weatherList
function loadWeather(lat, lng) {
$.get('http://api.openweathermap.org/data/2.5/find?lat=' + lat + '&lon=' + lng + '&cnt=10').done(function(data) {
// clear weather list
weatherList.remove(function() { return true; });
// insert items
weatherList.insert(data.list);
});
}
// Погода в Киеве
loadWeather(50.4666537, 30.5844519);
Посмотреть рабочий пример на JSBin.
В заключении
Хочу добавить, что идея не нова, есть github://MatthewMueller/array. Но код мне показался слишком перегруженным, что собственно может вылиться в проблемы с производительностью. Поэтому было принято решение «расширить» стандартный Array
.
Планы: есть желание покрыть библиотеку качественными тестами — было бы хорошо, если бы кто ни будь, кто хорошо разбирается в этом — помог.
Расширять список методов пока не планируется, за исключением метода removeListener()
.
Репозиторий Arr.js и документация (en).
Комментарии по улучшению приветствуются!
P.S.: В личных целях был разработан компонент https://github.com/jmas/list/blob/master/List.js который использует Arr.js. Компонент используется для создания списков, которые самостоятельно обновляют HTML при изменении массива данных. Компонент использует componentjs для разруливания зависимостей.
Автор: jMas