minato128 blog

minato128の公開メモ帳です。

Visual Studio Knockout.js Intellisense はどこまで効くのか?(ViewModelの別ファイル化とKnockout-ES5 pluginを入れてみる)

実際使うときは、ViewModelを外出ししたりプラグイン使ったりしますよね! VSでコーディングしてて、どこかのタイミングでインテリセンスが効かなくなること自体は把握していたのですが、特定できてなかったので改めて試してみました。

検証環境

  • VS2013.4 Ultimate
  • Web アプリケーションプロジェクト

検証

  1. ViewModel を別ファイル化して、ES5 plugin 入れる
    • 効かないと思ってたけど効いた!
    • 子要素まで
  2. 孫要素を作ってみる
    • 子要素まで効くけど、孫要素は効かない!
  3. SampleViewModelの初期化で、ダミーのjsonを食わせてみる
    • 孫要素も効く!
  4. SampleViewModelの初期化で、nullを食わせる
    • 子要素まで効くけど、孫要素は効かない!

結論と課題

ダミーのJSONでViewModelを初期化できるようにしておかないと子要素までしか補完できない。

  • VS側がヒントなしで解析できるのが子要素まで?
  • 本当にこの方法しかない?
  • WebAPI の呼び出しのコード入れても補完を効かせるには?
  • TypeScript、KO-Mapping 使ったらどうなる?

サンプルソース

変数名非常に適当です。。。

HTML 抜粋

<div data-bind="foreach:children">
    <table class="table table-bordered">
        <thead>
            <tr><th>First name</th><th>Last name</th></tr>
        </thead>
        <tbody data-bind="foreach: magoList">
            <tr>
                <td data-bind="text: mago1"></td>
                <td data-bind="text: mago2"></td>
            </tr>
        </tbody>
    </table>
</div>

<script src="Scripts/knockout-3.1.0.js"></script>
<script src="Scripts/knockout-es5.js"></script>
<script src="Scripts/JavaScript1.js"></script>
<script>
    var json1 = null;
    var json2 = {
        firstName: "first",
        lastName: "last",
        children: [
            { test1: "1111", test2: "1112", magoList: [{ mago1: "mago111" }, { mago1: "mago112" }] },
            { test1: "2221", test2: "2222", magoList: [{ mago1: "mago221" }, { mago1: "mago222" }] }
        ]
    }
    
    //ここで json1 を渡すか json2 を渡すかで、mago1 が補完できたりできなかったりする!!
    ko.applyBindings(new SampleViewModel(json2)); 
</script>

Javascript1.js

function SampleViewModel(data) {
    this.firstName = data.firstName;
    this.lastName = data.lastName;
    this.children = $.map(data.children, function(c){return new ChildModel(c)});
    ko.track(this);
}

function ChildModel(data) {
    this.test1 = data.test1;
    this.test2 = data.test2;
    this.test3 = data.test2;
    this.magoList = $.map(data.magoList, function(c){return new MagoModel(c)});
    ko.track(this);
}

function MagoModel(data) {
    this.mago1 = data.mago1;
    this.mago2 = data.mago1;
    ko.track(this);
}