Если для создания наблюдаемых объектов применяется метод observable()
, то для создания наблюдаемых массивов используется
метод observableArray(). Для этого массив передается в этот метод в качестве параметра:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Привязка массивов в KnockoutJS</title> </head> <body> <ul data-bind="foreach: phones"> <li> <p data-bind="text: name"></p> <p data-bind="text: company"></p> </li> </ul> <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.4.0.js"></script> <script> var viewModel ={ phones: ko.observableArray([ { name: "iPhone 6S", company: "Apple" }, { name: "Lumia 950", company: "Microsoft" }, { name:"Nexus 6P", company: "Huawei" }]) }; ko.applyBindings(viewModel); </script> </body> </html>
Наблюдаемые массивы, также как и наблюдаемые объекты, позволяют динамически изменять массив, и все изменения будут отражаться в html-элементе. Например:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Привязка массивов в KnockoutJS</title> </head> <body> <ul data-bind="foreach: phones"> <li> <p data-bind="text: name"></p> <p data-bind="text: company"></p> </li> </ul> <button id="addItemBtn">Добавить</button> <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.4.0.js"></script> <script> function Phone(name, company){ this.name = name; this.company = company; }; var viewModel ={ phones: ko.observableArray([ new Phone("iPhone 6S", "Apple"), new Phone("Lumia 950", "Microsoft"), new Phone("Nexus 6P","Huawei") ]) }; ko.applyBindings(viewModel); var addItemBtn = document.getElementById("addItemBtn"); addItemBtn.addEventListener("click", function (e) { viewModel.phones.push(new Phone("Samsung", "Galaxy S7 Edge")); }); </script> </body> </html>
Здесь в принципе тот же самый массив, только для упрощения создания элементов массива определена функция-конструктор Phone. И, кроме того, определена кнопка, по нажатию на которую происходит добавление нового элемента. И так как это наблюдаемый массив, то добавление нового элемента также приведет к добавлению нового элемента в элемент списка в разметке html:
С помощью слова as можно определить для перебираемого в цикле foreach объекта псевдоним:
<ul data-bind="foreach: { data: phones, as: 'phone'}"> <li> <p data-bind="text: phone.name"></p> <p data-bind="text: phone.company"></p> </li> </ul> <script> function Phone(name, company){ this.name = name; this.company = company; }; var viewModel ={ phones: ko.observableArray([ new Phone("iPhone 6S", "Apple"), new Phone("Lumia 950", "Microsoft"), new Phone("Nexus 6P","Huawei") ]) }; ko.applyBindings(viewModel); </script>
Хотя наблюдаемый массив представляет особый объект, с ним также можно производить ряд стандартных операций, что и с другими массивами в JavaScript.
В частности, в примере выше выполнялось добавление с помощью метода push()
. Также мы можем использовать еще ряд методов:
indexOf: возвращает индекс элемента в массиве
var viewModel ={ phones: ko.observableArray(["Apple", "Microsoft", "Huawei"]) }; console.log(viewModel.phones.indexOf("Apple"));
Метод возвращает индекс, либо, если элемент не найден, возвращается число -1.
slice: возвращает элементы из массива, начиная с определенного индекса и до определенного индекса. Например, выберем с 1 по 3 индексы
viewModel.phones.slice(1,3)
pop(): извлекает из массива последний элемент и возвращает его
unshift(value): вставляет новый элемент в начало массива
shift(): удаляет первый элемент из массива и возвращает его
reverse(): инвертирует массив
sort() : сортирует массив. По умолчанию для сортировки объектов используется алфавитный порядок. Но в более изощренных
случаях мы сами можем определить критерии сортировки, передав в качестве параметра в метод sort()
функцию сортировки:
var viewModel ={ phones: ko.observableArray([ new Phone("iPhone 6S", "Apple"), new Phone("Lumia 950", "Microsoft"), new Phone("Nexus 6P","Huawei"), new Phone("Galaxy S7","Samsung") ]) }; viewModel.phones.sort(function (left, right){ return left.name == right.name ? 0 : (left.name < right.name ? -1 : 1) });
Параметры функции left
и right
представляют сравниваемые элементы массива. Если они равны, функция возвращает 0. Если левый
элемент должен находиться перед правым, то возвращается число 1. Если наоборот - правый элемент должен находиться перед левым, то возвращается -1.
splice(startIndex, endIndex): удаляет из массива и возвращает элементы с индекса startIndex до индекса endIndex
remove(value): удаляет все элементы, которые равны value, и возвращает их в виде массива
removeAll(): удаляет все элементы из массива и возвращает их в виде массива