0

人々

私たちのプロジェクトは急速に規模が拡大しており、私は優れたJS市民になり、手遅れになる前にテストを実装したいと考えていました。Backbone with Backbone LayoutmanagerとHandlebarsテンプレートを使用してフロントエンドを作成しています。また、JasmineとJasmine-JqueryとSinonを使用してBackbone駆動型アプリをテストする方法に関する優れたブログ投稿をいくつか 読んだので、そのために行きます。

ただし、RequireJSモジュールを使用し、LayoutmanagerでBackboneを拡張し、Handlebarsテンプレートをプリコンパイルしているため、セットアップは少し変わっています。これらのライブラリの作成者によって提案されているように、テンプレートを非同期でプリコンパイルしています。長い一日の大部分を頭を悩ませて過ごした後、どのタイプの非同期jQuery/Ajax呼び出しも機能しないことに気付きました。 Jasmineを使用してアプリを実行します。$.ajax(...)と同期して呼び出しを行おうとしてasync: falseもうまくいきませんでした。LayoutmanagerJSソースを掘り下げてみると、すべてが非同期で発生することが意図されていることがわかりました。

とにかく、これが私が最終的にプリコンパイルを機能させることになった方法です:

Backbone.LayoutManager.configure({
    manage: false,

    prefix: "app/templates/",

    fetch: function(path) {
        var done;
        var that = this;

        // Concatenate the file extension.
        path = path + ".html";

        runs(function() {
            if (!JST[path]) {
                done = that.async()

                return $.ajax({ url: app.root + path, async: false }).then(
                    //Successhandler
                    function(contents) {
                        JST[path] = Handlebars.compile(contents);
                        JST[path].__compiled__ = true;
                        done(JST[path]);
                    },
                    //Errorhandler
                    function(jqXHR, textStatus, errorThrown) {
                        //Feil ved lasting av template
                        //TODO logg feil på en eller annen måte
                    }
                );
            }
            // If the template hasn't been compiled yet, then compile.
            if (!JST[path].__compiled__) {
                JST[path] = Handlebars.compile(JST[path]);
                JST[path].__compiled__ = true;
            }
        });

        waitsFor(function() {
            return done;
        }, "loading template", 500);
        return JST[path];
    },

    // Override render to use Handlebars
    render: function(template, context) {
        return template(context);
    }

});

解決策は、非同期ロジックをラップするrunsことwaitForでした。

質問ですが、これは最適なソリューションではないと思います。非同期呼び出しをラップするためだけにapp.jsを複製する必要があるためです。この問題に対するより良いアプローチはありますか?

十分に公平でない場合は、他の誰かがこの投稿から学んだことを願っています。

4

1 に答える 1

0

残念ながら、app.jsの複製を回避するソリューションは見つかりませんでした。ただし、そのファイルが変更されることはめったにないため、実際には問題にはなりません。ただし、上記の非同期処理をさらに堅牢にするために、いくつかの改善を行いました。

    waitsFor(function() {
        return JST[path] && JST[path].__compiled__;
    }, "loading template", 1000);
    return JST[path];

その後、その行done(JST[path]);を削除できます。

テストはより安定して実行されるようになりました。以前は、テンプレートが正しくロードされないためにテストが失敗することがありました。

これを答えとして受け入れる。

于 2013-01-16T15:51:34.453 に答える