0

バックボーンを使用しており、次のコードがあります。

render: function() {
    var displayData = this.model;

    fetchData('checkComplete', this.model.id, function(checkCompleteData) {
        displayData.complete = checkCompleteData; // Value is true
    });

    fetchData('showGraphicAssets', this.model.id, function(showGraphicsData) {
        $.each(showGraphicsData, function(index, value) {
            if (value.type === "GRAPHIC_A") {
                displayData.assetId = value.id; // Value is 808
            }
        });
    });

    console.log(displayData.complete); // Valus is undefined
    console.log(displayData.assetId); // Value is undefined

    var html = this.template.tmpl(displayData.toJSON());
    $(this.el).html(html);
}

fetchData = function(dataRequest, id, callback) {
request = '/show/' + id + '/completed.json';
$.ajax({
    url: '/app' + request,
    type: 'GET',
    dataType: 'json',
    success: function(data) {
        callback(data);
    }
});

};

ご覧のとおり、変数displayDataは関数の外で定義されていfetchDataます。コンテキスト内にプロパティを追加しようとするとfetchData機能し、コンテキスト外で使用しようとするとfetchData未定義になります。どうすればこれを修正できますか?

4

1 に答える 1

0

これは、JavaScript で発生する最も一般的な問題です。コールバックの非同期性を尊重しません。

コールバック関数で値を設定することはできず ( で行うようにdisplayData.assetId)、数行後にそれが使用可能になる必要があると想定することはできません。そうではありません。それは決してありません。

コールバックが完了すると利用可能になります。それらが 2 つあるので、複数の非同期呼び出しを処理するために特別に作成されたjQuery の$.when()関数(およびそのコンパニオン.then()、 、.fail()および) を使用します。.always()

render: function () {
    var self = this, model = self.model, template = self.template;

    $.when(
        $.get('/app/show/checkComplete/' + model.id + '/completed.json'),
        $.get('/app/show/showGraphicAssets/' + model.id + '/completed.json')
    )
    .then(function (checkCompleteData, showGraphicsData) {
        // this will receive the response data in the correct order

        model.complete = checkCompleteData;

        $.each(showGraphicsData, function (index, value) {
            if (value.type === "GRAPHIC_A") {
                model.assetId = value.id;
                return false; // break the $.each()
            }
        });

        $(self.el).html( template.tmpl(model.toJSON()) );
    })
    .fail(function () {
        // this will be called if either HTTP request fails
        // also check out the arguments and react accordingly to errors
    });
}

定型文が少なくて済むので、コードも短くなることに注意してください。

application/jsonビューが正しい Content-Type ( )を使用していることを確認したら、それで$.get()十分です。回避$.ajax()は視覚的にはるかにきれいです。

于 2013-03-17T08:00:39.077 に答える