Arr.js: события для стандартного массива

в 7:20, , рубрики: array, collection, javascript, данные, массив

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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js