knockoutでのList（配列）処理

    この記事は、knockout.js Advent Calendar 2015の３日目の記事です。 先に２日目に目を通すことを推奨しています。
    knockout , knockout-es5 , knockout.punches環境を想定しています。

knockoutでview部分でイテレータを用いるには、[foreach](http://knockoutjs.com/documentation/foreach-binding.html)を利用します。
[**このサンプル**](http://jsfiddle.net/MKGaru/25kqto8q/)では、FruitShopを例に、Shopで取り扱うフルーツ(Item)の名前と価格を一覧表示しています。

```js
this.items = [
    new Item("apple",60),
    new Item("banana",25),
    new Item("cinnamon",80),
    new Item("dragonfruit",120)
];
```
の部分を、

```js
this.items = [
    {name:"apple",price:60},
    {name:"banana",price:25},
    {name:"cinnamon",price:80},
    {name:"dragonfruit",price:120}
];
```
と書き換えても[問題はありません](http://qiita.com/MKGaru/items/69c9f032295146b2e1fa)

[先ほどのサンプル](http://jsfiddle.net/MKGaru/25kqto8q/)では、bindingの恩恵が少ないので、ShopへのItemの動的追加の[**サンプル**](http://jsfiddle.net/MKGaru/9304qhky/)を見てみましょう。

```html:index.html
<h1>Fruit Shop</h1>
<ul data-bind="foreach:items">
    <li>
        <span>{{name}}</span>
        <span>（{{price}}）</span>
    </li>
</ul>
<form data-bind="submit: register"> 
    <fieldset>
        <legend>商品登録：</legend>
        <label>商品名:<input type="text" id="item-name-input"></label>
        <label>価格:<input type="text" id="item-price-input"></label>
        <button>登録</button>
    </fieldset>
</form>
```

```js:script.js
function Item(name,price){
    this.name = name;
    this.price = price;
    ko.track(this);
}
function Shop(){
    this.items = [
        new Item("apple",60),
        new Item("banana",25),
        new Item("cinnamon",80),
        new Item("dragonfruit",120)
    ];
    ko.track(this);
}
Shop.prototype.register = function(){
    this.items.push(
        new Item(
            document.querySelector("#item-name-input").value,
            +document.querySelector("#item-price-input").value
        )
    );
};

var vm = new Shop();

ko.punches.enableAll();
ko.applyBindings(vm);
```

-------------------------------------

```js
document.querySelector("#foo").value
```
の部分は、

```js
document.getElementById("foo").value
```
でももちろんOKですし、
jQueryを使うのであれば、

```js
$("#foo").val()
```
でも何でもいいです。

イテレータの要素番号を取得する場合には、[$index](http://knockoutjs.com/documentation/foreach-binding.html#note-2-using-index-parent-and-other-context-properties)を利用します。
もっとも、[**このサンプル**](http://jsfiddle.net/MKGaru/tp42kab5/)ではolを使えばいいだけではあるのですが。  
また、$indexは0から始まる番号ですが、1から始めたい場合は、

[**このように**](http://jsfiddle.net/MKGaru/sjxhbmkk/) ```{{ $index() + 1 }}```とします。

view部分で`{{ }}` でくくられた中身は　ko.observale()のgetterを展開してくれますが、 ko.observable()はあくまで関数なので、
関数になんらかのものを結合すると、関数が文字列になってしまうので、このようにする必要があります。
knockout-es5で適用した部分は、object.defineされているのですが、　生のknockoutではko.observableで実装されているのがもどかしくもありますが、しょうがないですね。

また、蛇足ですが先ほどのサンプルをTypescriptで書くと次のようになります。

```ts
class Item{
    constructor(
        public name:string,
        public price:number
    ){
        ko.track(this);
    }
}
class Shop{
    public items:Item[] = [
        new Item("apple",60),
        new Item("banana",25),
        new Item("cinnamon",80),
        new Item("dragonfruit",120)
    ];
    constructor(){
        ko.track(this);
    }
    public register(){
        this.items.push(
            new Item(
                document.querySelector("#item-name-input").value,
                +document.querySelector("#item-price-input").value
            )
        );
    }
}

var vm = new Shop();

ko.punches.enableAll();
ko.applyBindings(vm);
```

------------------------------------------------------------------------

配列への値の追加・削除は次のように行います。　これらはバニラのjavascriptと同じです。

* ``list.push(value)`` ``list``という配列の末尾に、``value``を追加  
* ``list.splice(index,length)`` ``list``という配列の、``index``番目から、``length``個の要素を削除

listを空にしたいからといって、listに空配列を上書きをすることは非推奨です（ko-es5でtrackしているのであれば禁止ではありません）。 ~~`` list = [] ``~~