2009-06-01 14 views
39

Tôi đang triển khai gọi lại cho thư viện javascript 3Party và tôi cần trả lại giá trị, nhưng tôi cần lấy giá trị từ máy chủ. Tôi cần phải làm một việc như sau:

3rdPartyObject.getCustomValue = function { 
    return $.getJSON('myUrl'); 
} 

getJson sử dụng XMLHttpRequest (tôi tin) có cả hành vi đồng bộ và không đồng bộ, tôi có thể sử dụng hành vi đồng bộ không?

+3

Và tại sao bạn không thể sử dụng gọi lại để trả lại/nhận giá trị? Ngoài ra, hãy thử tránh các hành vi đồng bộ càng nhiều càng tốt, vì nó sẽ khóa giao diện người dùng trình duyệt trong quá trình xử lý của nó. – PatrikAkerstrand

+0

Mã gọi không hỗ trợ gọi lại. – tpower

Trả lời

103

Nhìn vào mã nguồn jQuery, đây là tất cả $.getJSON làm:

getJSON: function(url, data, callback) { 
    return jQuery.get(url, data, callback, "json"); 
}, 

Và đây là tất cả $.get làm:

get: function(url, data, callback, type) { 
    // shift arguments if data argument was omitted 
    if (jQuery.isFunction(data)) { 
     callback = data; 
     data = null; 
    } 

    return jQuery.ajax({ 
     type: "GET", 
     url: url, 
     data: data, 
     success: callback, 
     dataType: type 
    }); 
}, 

Không ma thuật đen đó. Vì bạn cần để tùy chỉnh những thứ khác hơn là $.getJSON chức năng cơ bản, bạn chỉ có thể sử dụng chức năng ở mức độ thấp $.ajax và vượt qua async option như sai:

$.ajax({ 
    type: 'GET', 
    url: 'whatever', 
    dataType: 'json', 
    success: function() { }, 
    data: {}, 
    async: false 
}); 
+8

Câu trả lời tuyệt vời :-) –

+0

khi bạn chuyển 'không đồng bộ: false' thì làm thế nào để bạn nhận được thông báo lỗi từ '$ .ajax'? –

+1

Các phương thức tiện lợi này gần giống như các giá trị đặt trước cho hàm $ .ajax. Chúng chỉ hữu ích nếu bạn đang sử dụng các tùy chọn ajax chính xác đó. – styfle

3

Nhưng trừ khi tôi nhầm lẫn mã này sẽ không hoạt động:

3rdPartyObject.getCustomValue = function { 
    var json = $.ajax({ 
    type: 'GET', 
    url: 'whatever', 
    dataType: 'json', 
    success: function() { }, 
    data: {}, 
    async: false 
    }); 

return json; 
} 

Khi $ .ajax trả về đối tượng XHR không phải đối tượng json được phân tích cú pháp.

Bạn sẽ cần phải làm một cái gì đó giống như:

var jsonLoader = function(url){ 
    this.url = url; 
    this.rawData = {}; 
    this.getRawData(); 
}; 

jsonLoader.prototype.getRawData = function(){ 

    var json = $.ajax({ 
     type: 'GET', 
     url: this.url, 
     dataType: 'json', 
     success: this.getRawData(this), 
     data: {}, 
     async: false 
    }); 
}; 

jsonLoader.prototype. getRawData = function(self){ 
    return function(json){self.rawData = json;}; 
}; 

var loadMe = new jsonLoader("Data.json"); 
loadMe.rawData //has the parsed json object 

Trong thực tế có lẽ là một cách gọn gàng hơn nhiều để đạt được cùng

7
var jsonObjectInstance = $.parseJSON(
    $.ajax(
     { 
      url: "json_data_plz.cgi", 
      async: false, 
      dataType: 'json' 
     } 
    ).responseText 
); 
15

Bạn cũng có thể sử dụng sau đây trước khi thực hiện cuộc gọi của bạn :

$.ajaxSetup({ "async": false }); 

Tôi không biết phạm vi của thuộc tính "không đồng bộ", tôi nghi ngờ rằng đó là cấu hình chung. Vì vậy, hãy cân nhắc xem bạn có muốn thay đổi điều này thành true sau cuộc gọi đồng bộ của bạn hay không.

dụ:

3rdPartyObject.getCustomValue = function { 
    $.ajaxSetup({ "async": false }); 
    var result = $.getJSON('myUrl'); 
    $.ajaxSetup({ "async": true }); 
    return result; 
} 
+1

Tính năng này hoạt động! –

0

Phạm vi của tài sản async là toàn cầu, phương pháp của bạn sẽ đồng bộ hóa các cuộc gọi.

2

Nếu ai từng có để làm điều này trong đường ray, tôi có một cách khá sạch sẽ như thế này:

cài đặt điều khiển của bạn như thế này:

def my_ajax_action 

    respond_to do |format| 
     # if you use render, you won't need a view page, the ":json =>" part takes care of all 
     # the formatting 
     format.json { render :json => @variable_containing_json } 
    end 

end 

Thiết lập cuộc gọi trong Javascript

function doAjaxWork() { 

    var ret; 

    $.ajax({ 
     type: 'GET', 
     url: '/controller/action/param', 
     dataType: 'json', 
     complete: function(response) { 
      ret = eval('(' + response.responseText + ')'); 
     }, 
     async: false 
    }); 


    return ret; 
} 

Tất nhiên, đừng làm công cụ đồng bộ hóa này trừ khi bạn phải làm vậy. Oh và trong khi tôi đang hiển thị javascript với url trong đó, hãy xem JSRoutes ...nó làm cho chúng thật sạch sẽ.

Các vấn đề liên quan