0

国の選択リストにバインドされた一般的な jQuery アクションを作成しました。国の選択にバインドされています。変更されると、状態を取得するためにサーバーへの呼び出しが行われます...

$('#' + countryElementID).change(function () {
    var countryID = $('#' + countryElementID).val();
    $.ajax({
        type: 'POST',
        url: '/App/GetStatesByCountry',
        data: {
            id: countryID
        },
        dataType: 'json',
        success: function (result) {
            // build HTML replace via .html
        },
        failure: function (result) {
            // ...
        }
    });
});

これをトリガーしているコードは次のとおりです...

var populateCompanyInfo = function (resultData) {

var populateList = {
    CompanyName: 'input',
    Address1: 'input',
    Address2: 'input',
    City: 'input',
    Zip: 'input',
    Email: 'input',
    Phone: 'input',
    Fax: 'input',
    CountryID: 'select',
    StateID: 'select',
    Active: 'toggle'
}

$.each(populateList, function (name, value) {
    var a = eval('resultData.' + name);
    var sectionID = 'RealtyCompany';
    if (a != null || a != '') {
        if (value == 'input') {
            // ...
        }
        if (value == 'select') {
                var a = eval('resultData.' + name);
                $('#select' + sectionID + name).val(a);
                $('#select' + sectionID + name).trigger('change');
        }
        if (value == 'toggle') {
            // ...
        }
    }
});

私が抱えている問題は、州が設定される前に StateID を選択することです (国のドロップダウンの変更からトリガーされます)。

変数が渡されるまで基本的に待機する国のドロップダウンの一般的なアクションで渡すことができる変数はありますか? 遅延アクションの 1 つを jQuery に組み込む方法を考えてみましたが、これを行う方法を見つけるのに苦労しています。

4

1 に答える 1

0

しばらくこれを見た後、ペニーが落ちました-つまり、私は質問を理解したと思います. 私が実際の回答を書いたかどうかはまだわかりません。

どちらの方法でも、重要なことは、jqXHR の「約束」(AJAX を介して選択した国の州を取得することから生じる) を他のスコープで利用できるようにすることです。国選択要素に適用される jQuery.data('fetchData')オブジェクトのプロパティを設定することで、これを行うことにしました。

次に、.each(populateList, ...)ループの仕組み (変更しようとはしていません) により、jqXHR もループ内の 2 つの分岐間で外部メンバーとして渡す必要があります。別のアプローチが利用可能ですが、私が思いついたものはすべて、少なくとも同じくらい面倒でした。

オブジェクトの.data()存在が保証されていないため、スクリプトに大量の追加を行うにはかなりの安全性が必要です。より少ないコードで同じ目的を達成するためのより簡単な方法がある可能性は十分にあります。

コードは次のとおりです。

$(function() {
    var countryElementID = 'selectRealtyCompanyCountryID';
    $('#' + countryElementID).change(function () {
        var $this = $(this);
        var jqXHR = $.ajax({
            type: 'POST',
            url: '/App/GetStatesByCountry',
            data: { id: $this.val() },
            dataType: 'json',
            success: function (result) {
                // Build HTML replace via .html()
            },
            failure: function (result) {
                // Generic error handler
                alert('Generic error handler');
            }
        });
        var fetchData = $this.data('fetchStates');// May of may not exist.
        if(fetchData) fetchData.jqXHR = jqXHR;//Make the jqXHR available to other scopes via the DOM.
    });

    var populateCompanyInfo = function (resultData) {
        var populateList = {
            CompanyName: 'input',
            Address1: 'input',
            Address2: 'input',
            City: 'input',
            Zip: 'input',
            Email: 'input',
            Phone: 'input',
            Fax: 'input',
            CountryID: 'select',
            StateID: 'select',
            Active: 'toggle'
        }
        var fetchPromise = null;

        $.each(populateList, function (name, value) {
            var a = resultData[name];
            var sectionID = 'RealtyCompany';
            if(a) {
                if (value == 'input') {
                    // ...
                }
                if (value == 'select' && name == 'CountryID') {
                    //Branch for the CountryID select menu
                    var $el = $('#select' + sectionID + name);
                    var fetchData = $el.data('fetchStates');
                    if(!fetchData) {
                        $el.data('fetchStates', {});
                    }
                    if(fetchData.jqXHR && fetchData.jqXHR.abort) {//safety
                        fetchData.jqXHR.abort();//Kill any outstanding ajax requests of the same type.
                    }
                    $el.val(a).trigger('change');
                    fetchPromise = data.jqXHR;//Make the new jqXHR object available to the 'StateID' branch next time round the .each loop.
                }
                if (value == 'select' && name == 'StateID') {
                    //Branch for the StateID select menu
                    if(fetchPromise && fetchPromise.done) {//May of may not be defined.
                        fetchPromise.done(function(data, textStatus, jqXHR) {
                            // At this point the States element is freshly populated with states.
                            // Here, do whatever is necessary once the States element
                            // eg. set its .val() then trigger its 'change' event.
                        }).fail(function(jqXHR, textStatus, errorThrown) {
                            // Display error message?
                            // Set the States element to a default value?
                            alert('Specific error handler');
                        });
                    }
                }
                if (value == 'toggle') {
                    //...
                }
            }
        });
    }
});

構文エラーを排除するためにテスト済み - それ以上のものはありません

編集

はい、単純化できます - here's some better code . ajax の失敗によるエラー メッセージが表示されます。状態のフェッチを完全にはシミュレートしていません。しかし、エラー メッセージは適切です。つまり、一連のイベントが正しいことを意味します。

于 2013-03-14T02:47:17.120 に答える