- PVSM.RU - https://www.pvsm.ru -

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

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 [1].

В заключении

Хочу добавить, что идея не нова, есть github://MatthewMueller/array [2]. Но код мне показался слишком перегруженным, что собственно может вылиться в проблемы с производительностью. Поэтому было принято решение «расширить» стандартный Array.

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

Расширять список методов пока не планируется, за исключением метода removeListener().

Репозиторий Arr.js и документация (en) [3].

Комментарии по улучшению приветствуются!

P.S.: В личных целях был разработан компонент https://github.com/jmas/list/blob/master/List.js [4] который использует Arr.js. Компонент используется для создания списков, которые самостоятельно обновляют HTML при изменении массива данных. Компонент использует componentjs [5] для разруливания зависимостей.

Автор: jMas

Источник [6]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/70405

Ссылки в тексте:

[1] Посмотреть рабочий пример на JSBin: http://jsbin.com/gidubu/2/

[2] github://MatthewMueller/array: https://github.com/MatthewMueller/array

[3] Репозиторий Arr.js и документация (en): https://github.com/jmas/arr

[4] https://github.com/jmas/list/blob/master/List.js: https://github.com/jmas/list/blob/master/List.js

[5] componentjs: https://github.com/componentjs/component

[6] Источник: http://habrahabr.ru/post/238197/