JavaScript で作るストアアプリにもBehaviorが!

この内容は Windows 8.1 Preview および Visual Studio 2013 Preview (の Blend) をもとに記述しています。

Windows 8 Dveloper Preview が出てから、 WinRT アプリ for XAML がでてから、ずーっと Behavior が欲しくって、でも DependencyObjectCollection がなく DataContext の伝搬ができないので、まっとうなのが作れないので、諦めてたのですが、今回からやっとこさ DependencyObjectCollection が乗りましたね。ちょっと Generic じゃないのが気になりますが、良しとしましょう。

で、MSDN ながめても Behavior らしきものはなかったので、作ろうかと思ってるところに乗ってるよって噂を聞いたので探してみました。結論的には XAML のほうはまだ見つかってません。 Build のビデオをまだ見切ってないのと、 Blend をいじり倒してないのであるかどうかは不明ですが。

上記で "XAML のほう" はって書いたのにはわけがあって、っていうかもうすでにタイトルにつけているのですが、なんと JavaScript のほうには乗ってました。予想外です。

以下のように Blend の「アセット」ペインをみるとしっかりと表示されています。

f:id:k_maru:20130630004354p:plain

ということで、さっそく使ってみました。使い方は簡単で、いつものように画面にドラッグドロップするだけ。今回はとりあえずボタンを置いて ToggleClassAction を貼り付けてみました。たぶん、何かのイベント(予想ではデフォルトは click で後から変更可能) をもとに指定した class 属性の値を設定、解除できると思われます。で、出来上がった HTML は以下のような感じ。

<button type="button" 
    data-blend-behavior="BehaviorActionTree_1">button</button>

data-blend-bahavior 属性に BehaviorActionTree_1 ってのが設定されていますが、詳細はなにも書かれてません。あれーっと思いながらプロジェクトの中を眺めてると actionList.json ってファイルが追加されてます。

f:id:k_maru:20130630005125p:plain

で、この中を見るとありました。

[
  {
    "name": "BehaviorActionTree_1",
    "behaviors": [
      {
        "type": "Blend.Behaviors.EventTriggerBehavior",
        "event": "click",
        "triggeredActions": [
          {
            "type": "Blend.Actions.ToggleClassAction"
          }
        ]
      }
    ]
  }
]

もう、この時点で「コレジャナイ」感が満載なわけですが、そこはめげずに見ていきましょう。

Silverlight/WPF では Behavior と一括りでいってますが、実際のところは "Behavior" と "Trigger/Action の組"のどちらかを設定します。が、こちらでは Trigger はなくなって TriggerBehavior って形になってますね。

読んでいくと、 最上位の name ってのが HTML の data-blend-behavior 属性の値と同じになってます。どうやら、この値を一致させて、同階層にある behaviors の内容を適用する模様。で、 behaviors の中は配列になっているので、同じ値で複数の behavior が設定できるのですね。

で、一番上の type が Blend.Behaviors.EventTriggerBehavior になってるので、「イベントを受けて何かを動かす振る舞い」ってことでしょう。 event の値は click になってます。なので、 「click を受けて何かを動かす振る舞い」ってことですね。

「何かを動かす振る舞い」の部分はその下の、triggerdActions の部分ですね。ここも配列なので複数の振る舞いを設定できるようですが、一つ目に画面で指定した Blend.Actions.ToggleClassActionが出てきます。ってことで、ToggleClassActionはそのままでクラスをトグルしてくれるので「イベントを受けて、クラスをトグルする振る舞い」って感じで指定されています。

さて、ここまで見てきてあれなのですが、指定の中に「何ていう」クラスをトグルするかは出てきてません。謎です。っていうか、どう考えても必ず指定が必要なのでどうにかして描けるはずです。で、HTML なのでどこかにソースがあるはずと思ってもう一回プロジェクトをよく見たらありました。"Blend.Runtime.1.0.js" ってのが、 js フォルダの直下に。再び「コレジャナイ」感が満載なわけですが、そこもめげずに見ていきましょう。

とりあえず、開いて「ToggleClassAction」を検索してみると、ありました。className ってプロパティを指定しろっぽいことが書かれてます。ほかには targetSelector ってのもありますね。

{
  // Property Meta-data (for JSON parsing)
  className: { type: String },
  targetSelector: { type: String }
}

っていうことで、className を追加してみました。値は "behavior-on" ってしてます。

"triggeredActions": [
  {
    "type": "Blend.Actions.ToggleClassAction",
    "className": "behavior-on"
  }
]

上記で指定した "behavior-on" って値が、ボタンをクリックするたびについたり消えたりするはずです。とりあえず、css で .behavior-on ってクラス名には背景章を赤で指定しておきました。

.behavior-on{
  background-color: red;
}

で、実行してボタンを押してみます。

f:id:k_maru:20130630011624p:plain

無事にクリックしたら、赤になって、もう一回クリックしたらもとに戻りました。

さて、ここまでで使い方は何となくわかりました。「コレジャナイ」感がもう絶頂なんですが、なんやかんや言うても作れもしないのに文句は言っちゃダメと思い、とりあえず作ってみました。もちろん作り方はソースをよみます(長くなっているので作り方はまた別途っていうことで)

作ったコードは以下のような感じ。ダイアログを上げるだけですね。

WinJS.Namespace.define("App.Actions", {
  AlertAction: WinJS.Class.derive(Blend.Actions.ActionBase,
    function () {
    }, {
      message: "",
      execute: function () {
        Windows.UI.Popups.MessageDialog(this.message).showAsync();
      }
    }, {
      message: { type: String }
    })
});

上記で作ったものを定義に追加すると以下のような感じになります。

"triggeredActions": [
  {
    "type": "Blend.Actions.ToggleClassAction",
    "className": "behavior-on"
  }, {
    "type": "App.Actions.AlertAction",
    "message": "Hello WinJS-Blend Behavior!"
  }
]

動かすと無事にダイアログが表示されました。

f:id:k_maru:20130630012637p:plain

まぁ、最後ちょっと飛ばしまくりでした、そのうちキレイにまとめます。


まぁ、何回も書いている通り「コレジャナイ」感でいっぱいなので、使うか使わないかは今後のなりゆき次第かなと。しかし、 XAML のほうの Behavior はどないのっとるのか・・・。