LoginSignup
0
2

More than 5 years have passed since last update.

knockoutでのList(配列)処理

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

knockoutでview部分でイテレータを用いるには、foreachを利用します。
このサンプルでは、FruitShopを例に、Shopで取り扱うフルーツ(Item)の名前と価格を一覧表示しています。

this.items = [
    new Item("apple",60),
    new Item("banana",25),
    new Item("cinnamon",80),
    new Item("dragonfruit",120)
];

の部分を、

this.items = [
    {name:"apple",price:60},
    {name:"banana",price:25},
    {name:"cinnamon",price:80},
    {name:"dragonfruit",price:120}
];

と書き換えても問題はありません

先ほどのサンプルでは、bindingの恩恵が少ないので、ShopへのItemの動的追加のサンプルを見てみましょう。

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>
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);

document.querySelector("#foo").value

の部分は、

document.getElementById("foo").value

でももちろんOKですし、
jQueryを使うのであれば、

$("#foo").val()

でも何でもいいです。

イテレータの要素番号を取得する場合には、$indexを利用します。
もっとも、このサンプルではolを使えばいいだけではあるのですが。

また、$indexは0から始まる番号ですが、1から始めたい場合は、

このように {{ $index() + 1 }}とします。

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

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

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 = []

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2