2

JavaScript はほとんどの Web ソリューションでますます重要な役割を果たしていますが、JS コードをビューの仕様から分離することは、サーバー側のコードよりもはるかに難しいことがわかりました。

メンテナンスの負担を軽減し、マイナーなビューの変更に対して可能な限り回復力を持たせるために、JS コードを分離するために人々はどのような手法を使用していますか?

具体的な例を提供するために、次のようなビューがあります。

<div id="signin" class="auth">
    <h2>Sign in</h2>
    <div id="resultbox" class="box" style="display: none;"></div>

    <div class="form">
        <p>Required fields are marked <span class="yellow">*</span></p>
        <form action="@Url.Action( MVC.Account.Authenticate() )" method="post" id="authform">
            <label for="Identification">Alias or email <span class="yellow">*</span></label></p>
            @Html.TextBoxFor( m => m.Identification, new { size="22", tabindex="1" } )

            <label for="Password">Password <span class="yellow">*</span></label></p>
            @Html.PasswordFor( m => m.Password, new { size="22", tabindex="2" } )

            <a href="#" class="but_styled" id="btn_signin" tabindex="3">Sign in</a>
        </form>
    </div>
</div>

JS 部分は 2 つのファイルに分割されます。1 つ目は「ビジネス ロジック」クラスで、2 つ目は主に配線に使用されます。

(function (pp, $, undefined) {
    pp.account = {};

    function hideResultBox() {
        var box = $('#resultbox');
        box.hide();
        box.removeClass('info_box').removeClass('error_box');
    }
    function showResultBox(result) {
        var box = $('#resultbox');
        if (result.Success === true) {
            $('#resultbox_content').html(result.Message);
            box.addClass('info_box').show();
        } else {
            $('#resultbox_content').html(result.Message);
            box.addClass('error_box').show();
            var messages = '';
            for (var error in result.Errors) {
                messages += '<li>' + result.Errors[error] + '</li>';
            }
            if (messages !== '')
                $('#resultbox_content').append('<br /><ul>' + messages + '</ul>');
        }
    }

    pp.account.authenticate = function (data) {
        hideResultBox();
        $.post('/account/authenticate', data, function (result) {
            showResultBox(result);
            if (result.Success === true) {
                setTimeout(function () { window.location = result.Url; }, 1000);
            }
        });
    };
})(window.pressplay = window.pressplay || {}, jQuery);

そして配線部分:

$(document).ready(function () {
    $('#signin a').live('click', function () {
        var form = $(this).closest('form').serialize();
        pressplay.account.authenticate(form);
        return false;
    });
});

上記のコードの問題は、ビューの外観 (存在しなければならない要素 ID、構造など) と密接に結びついていることですが、それを改善する方法については良い考えがありません。

この道を進み続けると、JS ファイルは、あらゆる種類のビュー固有のものと組み合わされた適切にカプセル化されたロジックの混乱になってしまうように思えます。

これは私が望むことができる最善の方法ですか、またはこの混乱の一部を回避するために適用できるテクニックはありますか?

これを改善する方法に関する私自身のアイデアは、サーバー側で生成されたある種の「要素セレクター」JS クラスを構築することを中心に展開しています。これにより、クラスと要素 ID への文字列参照をそれほど多く使用せずに JS を記述できます。しかし、それをどのように生成するのか、または最終的に維持するのが悪いのかどうかはわかりません。

4

3 に答える 3

3

いくつかの考え:

  • 要素の "id" 値に基づいて機能を設定しないでください。ただし、"自然に" 一意である要素を実際に含むビュー機能は除きます。可能な限り代わりにクラスを使用してください。
  • 「data-」属性を使用して、HTML から JavaScript に機能構成情報を伝達します。(しかし、「data-」属性にコードを入れないでください。私の意見では、それは本当にひどい考えです。申し訳ありませんが、Knockoutのファンです。各自に。)
  • イベント pub/sub システムを使用して機能の「バンドル」間で通信し、相互依存関係を制御します。
  • <body>「配線」の効率を高めるために、クラスを使用してさまざまな種類のページを特徴付けます。そうすれば、機能コードは、特定のページで考慮する必要があるかどうかを非常に迅速に判断できます。

編集<form>— 最後の 1 つを明確にするために:日付ピッカー、オートコンプリート入力、またはそのようなものなど、ページに関係するいくつかの機能があるとしましょう。特定の種類のフォームでのみ意味をなす機能が存在する場合があります。このような場合、body クラスを使用すると、要素が影響を与えるために機能がわざわざ DOM を調べる必要があるかどうかを簡単に判断できます。

if ($('body').is('.password-form')) { 
  // perform specific initializations
}

私が現在関わっている Web アプリケーションは、それほど大きくはありませんが、些細なことでもありません。サイト全体で JavaScript の大きなコレクションを 1 つだけ保持し、それをすべてのページに同じように含めることができることがわかりました。(現在) パフォーマンスに関する懸念はありません (まあ IE7 は遅いですが、この手法はエラーの原因ではありません)。それ)。

于 2011-11-06T13:39:42.873 に答える
1

JavaScript はまだビューの一部であるため、JavaScript をビューと絡ませる設計が悪いとは思いません。

生活を楽にするためにできることに関しては、一般的な JavaScript コーディングの状況を見つけて、それらをビューからリファクタリングし、それを使用および再利用できる共通のライブラリにリファクタリングするために、できることは何でもする必要があると思います。たとえば、hideResultBox を次のように書き直した場合:

function hideElement(var jqElementSelector, var cssClass1, var cssClass2 var cssClass3) {
    var element = $(jqElementSelector);
    element.hide();
    element.removeClass(cssClass1).removeClass(cssClass2).removeClass(cssClass3);
}

そして、このビューで呼び出しを次のように置き換えることができます。

CommonLib.hideElement('#resultbox', 'info_box', 'error_box');

この方法では、少なくとも、維持する JavaScript がそれほど多くありません。また、ロジックを渡すのではなく、名前と ID だけを渡すので、サーバーから JavaScript コール ポイントを生成するのが簡単になります。

于 2011-11-06T13:39:11.467 に答える
1

IDの代わりに、より「機能的な方法」で考えます...つまり、最初にjavascriptコードの機能を考えてから、ビューで使用できるようにコードを作成します。

違いがわかりますか?

あなたがやっている方法は次のとおりです:最初にビュー、次にjavascriptコード...私が提案するのは:最初にjavascript、次にビュー要素です。このようにして、再利用可能な JavaScript コードベースをコーディングしていることを確信できます。

ID を使用する代わりに、クラスを使用します。再利用できる汎用ライブラリのようにコードを作成します。たとえば、「.myClass div a」...そのdivは再利用性を殺しています...内部クラス「.myClass .innerClass a」に置き換えます。このようにして、クラスをビューに適用できます、ビューがコードを支配しないようにします。

ビューに直接配置する JavaScript コードをできる限り最小限に抑えます。独自のライブラリへのメソッド呼び出しを使用し、シンプルでわかりやすいメソッド名を使用してください。JavaScriptをまとめてみてください。宣言型の JavaScript を使用しないようにしてください...既にこれを行っていることがわかります。これが行く方法です!=)

デカップリングは保守性を向上させる実証済みの方法であるため、保守性について心配する必要はありません。

于 2011-11-06T13:39:18.363 に答える