Javascript Backbone在更高的上下文中存储值

时间:2013-03-17 05:28:07

标签: javascript

我正在使用骨干,我有这个代码:

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上下文之外使用它时,它会导致未定义。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

这是人们使用JavaScript时最常见的问题。您不尊重回调的异步性质。

您无法在回调函数中设置值(就像使用displayData.assetId一样)并假设它必须在几行之后可用。不是。它永远不会。

回调完成后即可使用。由于你有两个,使用jQuery的$.when()function(和它的同伴.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),那么$.get()就足够了;避免$.ajax()在视觉上更清洁。