こんにちは。きんくまです。
おとといBackboneのメモ記事書いたのだけど、TypeScriptに移したらうまくいかなかったので、またまたメモです。
具体的にいうと、Collectionのmodelプロパティの設定についてです。
こんなコードがあったとします。
module sample{ export class Product extends Backbone.Model{ name:string; price:number; defaults(){ return { name:"名無しの製品" ,price:0 } } initialize(){ var defaults:any = this.defaults; this.name = this.get('name') || defaults.name; this.price = parseInt(this.get('price')) || defaults.price; } } export class ProductsCollection extends Backbone.Collection{ filePath:string = "images/xxxx.png"; model = Product; //ココの位置 constructor(options?:any){ super(options); } } } $(()=>{ var products = new sample.ProductsCollection([ { name:"炊飯器" ,price:8000 } ,{ name:"掃除機" ,price:10000 } ]); var results = products.where({name:"炊飯器"}); console.log(results[0]); });
これをやるとProductsCollectionのところがうまく機能しませんでした。TypeScriptのバージョンは1.0.0.0です。
理由は吐き出されたjsをみるとわかるのだけど、コンストラクターのsuperが呼ばれたあとにmodelのプロパティを設定しているからでした。
はきだされたjsを一部抜粋
var ProductsCollection = (function (_super) { __extends(ProductsCollection, _super); function ProductsCollection(options) { _super.call(this, options); this.filePath = "images/xxxx.png"; this.model = Product; } return ProductsCollection; })(Backbone.Collection);
これでもうまくいくためには、Collectionをnewするときに、引数にデータをいれないで、あとから設定するという方法があります。前の記事はfetchであとからデータをいれたので、大丈夫だった。
だけど、もしModelとCollectionを入れ子にしてある場合はコンストラクターにデータが入った状態で、連鎖していくからこの状態だとマズイです。
なので、コンストラクターの前に入れておけば良いんじゃない?と思ってこのコードを書くとコンパイルエラーが出ます。
export class ProductsCollection extends Backbone.Collection{ filePath:string = "images/xxxx.png"; //注1 constructor(models?:any){ this.model = Product; //ココ! super(models); } }
エラーの内容はsuperはコンストラクターで一番最初に呼ばれないとイクない!というもの。
error TS2104: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.
ちなみにこのエラーは何故か、上のソースの//注1の部分の = 以下を削除すると解除されます。つまりインスタンスプロパティに代入せず宣言だけならオッケー。
でも、代入したいし。
解決策
で、いろいろとネットを検索したりしたのだけど、いい解決策がなくて困ってたところでもう一度Backbone.jsのリファレンスを見たところで解決しました。(実際はDashというアプリで見てます。なんか今みたら2000円もしてるけど、前って500円くらいじゃなかったけ?と思ってレシート検索したら、1年前の正月に450円で買ってた)
やっぱ公式リファレンスって大事ですな。
>> constructor / initialize
いろいろ書いたくせに、第二引数に入れるだけで良かったという、、orz すみませんすみません。
export class ProductsCollection extends Backbone.Collection{ filePath:string = "images/xxxx.png"; constructor(models?:any){ super(models, { model:Product }); } }
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ