この記事は、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の動的追加のサンプルを見てみましょう。
<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>
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 = []