プログラミング/JavaScript/Knockout.js のバックアップ(No.6)

更新


公開メモ

Knockout.js

ブラウザ上の DOM を JavaScript で操作するために、 JavaScript 上の ViewModel オブジェクト と DOM とを リンクさせ、ViewModel の変更が自動的に DOM に 反映されるようになる超お手軽なライブラリ

非常に使いやすいテンプレート機能や、 Computed Observable によるデータ依存関係の追跡も、 地味に重要な機能

と理解しました。

最近は prototype.js ははやらないので、

  • html5 : 最新の html 標準
  • css3 : 最新の css 標準
  • jQuery : 汎用ライブラリ 主に DOM 操作
  • Knockout.js : View-ViewModel 関係を構築するためのフレームワーク
  • knockout.validation.js : Knockout.js 上での Validation ライブラリ
  • Underscore.js : 汎用ライブラリ
  • reset.css : ブラウザ依存スタイルのリセット用コード
  • html5shiv.js, css3-mediaqueries.js : 古い IE 対策

あたりを使うのが定番なのでしょうか?

情報源

試しに学会アブストラクトのWeb投稿フォームを作ってみる

knockoutjs + knockout-validation で、 jsfiddle の使い方も学びながらちょっとずつやってみてます。

http://jsfiddle.net/e2yFs/2/embedded/result,js,resources,html,css/

現状、とりあえず動くことは動きますが、下記の knockout.validation のバグのために Submit を押すと Validation にものすごく時間がかかります。 (2014-05-13 追記:その後のアップデートのため、現状は動かなくなっています)

Issue #354 で提案した改善を施した物がこちらで、Submit も問題なく動きます。 (2014-05-13 追記:こちらは動くと思います)

http://jsfiddle.net/e2yFs/5/embedded/result,js,resources,html,css/

  • Submit 時に確認画面を出す
  • データを保存せずページ遷移しようとした時に確認画面を出す
  • cookie に?データを一時保存する ← 日付入りでn個まで
  • 一時保存データの一覧を出す
  • 一時保存データの load, save(overwrite), delete

とか、試したい。

knockout-validation の現状

(2014-05-13 追記)

どうも、knockout-validation は開発がうまく行っていないみたいですかね。

2014-05-13 現在、最新リリースは2年前で、オープン issue が溜まりまくっています。

かなり残念ですが、今後も長く使っていくライブラリとしては採用しづらいのかもしれません。

気付いたこと

以下の2つは knockout.validation の Issue #354 で解決済みだと思います

https://github.com/Knockout-Contrib/Knockout-Validation/issues/354

このあたりのコードを見ていると、まだまだ枯れたライブラリとは 言えないようで、自己責任で使っていくしかない感じがひしひしと。

子オブジェクトに親オブジェクトへのリンクを持たせてはならない

ここでの親子は継承関係ではなくてコンポジット関係。

あと、恐らく knockout.validation の問題かも。

子オブジェクトが親オブジェクトへのリンクを持っていると、 ko の依存関係の検出時に無限ループしてしまうみたいです。

LANG:js
// これはダメ

Child = function(parent) {
  this.parent = parent;
};

Parent = function() {
  this.child = new Child(this);
};

Parent 依存している Child が依存している Parent が依存している Child が・・・

と追っていってブラウザが固まります(泣

どうしても Child に Parent へのリンクを持たせたいときは、 関数にすれば回避できるようです。

LANG:js
// これならOK

Child = function(parent) {
  this.parent = function(){ return parent; };
};

Parent = function() {
  this.child = new Child(this);
};

子オブジェクトが親オブジェクトを知っていなければならないという時点で 設計がおかしいという指摘もあるかと思いますが、全体の調和を見るような Validation を実装しようとすると親へのリンクが欲しくなる場合があるような?

もっと良い回避方法があるのかもしれないですが、とりあえずメモということで。

そうじゃなくても依存解析に非現実的な時間がかかることがある?

knockout.validation の traverse がものすごく時間がかかる。

理由を調査中。

observable に結びつけられた UI が正しく更新されないとき

knockout の UI を強制的に refresh するには、

observable.valueHasMutated();

を呼べばいいそうです。

普通はそういうことは起きないはずなんですが、 ObservableArray.sort と select の組み合わせで select の表示がおかしくなり、 それを正しく戻すために .valueHasMutated() が必要でした。(knockout-3.0.0.js)

質問・コメント





Counter: 5008 (from 2010/06/03), today: 1, yesterday: 3