3

私はデュランダルベースのSPAで遊んでいます.「ビュー」と「ビューモデル」を持つという彼らの慣習に従って、基本的な機能は正常に動作しています. つまり、somepage.html&を使用しsomepage.jsます。

しかし、よりインタラクティブな UI 要素 (折りたたみ可能なアコーディオンや有益なポップアップなど) を追加する場合、これらのイベントを処理する JavaScript はどこに行けばよいのでしょうか? それをsomepage.jsviewmodelファイルに入れるのは「においがする」わけではありません-それは...ビューモデルのためです!

ベスト プラクティスの観点から、somepage.htmlファイルにスクリプト ブロックを含める方がよいでしょうか? 例えば

<section>
    <!- html markup and data-binding goes here>
</section>

<script type="text/javascript">
    <!-- UI-only Javascript goes here>
</script>

それとももっと良い方法がありますか?

4

3 に答える 3

3

私もこれに苦労しており、ビュー関連のものをviewModelに入れるのが臭いことに同意します。あなたが話していることをする必要があった理由は、委任されたイベント ハンドラーをアタッチすることでした。これは、提案されているように、カスタム バインディングまたはウィジェットを使用して行うことはできません。

同僚と私が思いついた最善の解決策はviewAttached、viewModel からイベントを伝達し、「ビュー ファイル」でイベントをリッスンすることでした。

例として「awesome」という名前のビューを使用すると、次のような命名規則を使用しています。

  • モデルの表示- viewmodels/awesome.js
  • 表示- views/awesome.html
  • ファイルを表示- views/awesome.html.js

これは、私たちが行っていることの単純化されたバージョンです。

ビューモデル/awesome.js:

define([
    "durandal/app",
    "durandal/system",

    // require the view file; note we don't need a reference to it,
    // we just need to make sure it's loaded
    "views/myView.html"
],

function (app, sys) {
    var viewModel = {
        // whatever
    };

    viewModel.viewAttached = function(view) {
        // Create a namespace for the event
        var eventNamespace = sys.getModuleId(viewModel)
            .replace("viewmodels", "")
            .replace("/", ".");

        // This will evaluate to 'awesome.viewAttached'
        var eventName = eventNamespace + ".viewAttached";

        // Trigger the event and pass the viewModel and the view
        app.trigger(eventName, viewModel, view);
    };

    return viewModel;
});

ビュー/awesome.html.js:

define([
    "durandal/app"
],

function (app) {
    var module = {
        viewAttached: function(viewModel, view) {
            // do your thing! make sure any selectors you use use the view as the parent selector,
            // because you're not guaranteed that your view is in the DOM (only that it's attached
            // to its parent).
            var $submit = $("#submit", view);
        }
    };

    // wire-up
    app.on("awesome.viewAttached", module.viewAttached);

    // export
    return module;
});

それが役立つことを願っています。

于 2013-05-17T03:43:37.730 に答える
3

純粋な GUI JavaScript 要素は、html データ属性によって UI にバインドする必要があります。たとえば、ブートストラップ アコーディオンには次の html があります(ブートストラップ ドキュメントはこちら)。

<div class="accordion" id="accordion2">
  <div class="accordion-group">
    <div class="accordion-heading">
      <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseOne">
        Collapsible Group Item #1
      </a>
    </div>
    <div id="collapseOne" class="accordion-body collapse in">
      <div class="accordion-inner">
        Anim pariatur cliche...
      </div>
    </div>
  </div>
.......

ページの下部で参照されているブートストラップ JavaScript ファイル。

于 2013-05-16T19:31:32.083 に答える
1

viewAttached は非常に危険な機能です... すべての JS コードをそこに入れたくなりますが、理想的ではありません。私が見つけた1つのちょっとした癖は、ネストされたビューモデルで

親 ステップ 1 (子 1) ステップ 2 (子 2)

親スイッチ (child1 <--> child2)

親が子ビューの操作 (子 1 から子 2 へのスワップ) を行う場合、viewAttached は子で適切に起動されず (その時点では DOM はまだ利用可能ではありません)、親は既にアタッチされているため、viewAttached は実行されません。親でも!

したがって、突然、すべての JS モジュールが機能しなくなることがわかり、外部 JS によって変更する必要がある要素に対して ko customBindings を実行する必要があります。

于 2013-05-26T07:32:16.810 に答える