可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am trying, in vain it seems, to be able to pass additional parameters back to the success callback method that I have created for a successful ajax call. A little background. I have a page with a number of dynamically created textbox / selectbox pairs. Each pair having a dynamically assigned unique name such as name="unique-pair-1_txt-url" and name="unique-pair-1_selectBox" then the second pair has the same but the prefix is different.
In an effort to reuse code, I have crafted the callback to take the data and a reference to the selectbox. However when the callback is fired the reference to the selectbox comes back as 'undefined'. I read here that it should be doable. I have even tried taking advantage of the 'context' option but still nothing. Here is the script block that I am trying to use:
<script type="text/javascript" language="javascript">
$j = jQuery.noConflict();
function getImages(urlValue, selectBox) {
$j.ajax({
type: "GET",
url: $j(urlValue).val(),
dataType: "jsonp",
context: selectBox,
success:function(data){
loadImagesInSelect(data)
} ,
error:function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
function loadImagesInSelect(data) {
var select = $j(this);
select.empty();
$j(data).each(function() {
var theValue = $j(this)[0]["@value"];
var theId = $j(this)[0]["@name"];
select.append("<option value='" + theId + "'>" + theValue + "</option>");
});
select.children(":first").attr("selected", true);
}
</script>
From what I have read, I feel I am close but I just cant put my finger on the missing link. Please help in your typical ninja stealthy ways. TIA
****UPDATE****
Nick is a true Ninja. They should invent a new badge for that! His answer below does the trick. As he mentions it's 1.4 specific but I can live with that. Here is my final code that is working for any Ninjas in training (and my future reference):
<script type="text/javascript" language="javascript">
$j = jQuery.noConflict();
function getImages(urlValue, selectBox) {
$j.ajax({
type: "GET",
url: urlValue+ '?callback=?',
dataType: "jsonp",
context: selectBox,
success: jQuery.proxy(function (data) {
var select = $j(this);
select.empty();
$j(data).each(function() {
var theValue = $j(this)[0]["@value"];
var theId = $j(this)[0]["@name"];
select.append("<option value='" + theId + "'>" + theValue + "</option>");
});
select.children(":first").attr("selected", true);
}, selectBox),
error:function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
</script>
回答1:
Updated: If you're using jQuery 1.4 use this to simplify things a bit:
success: jQuery.proxy(function (data) {
var select = $j(this);
select.empty();
$j(data).each(function() {
var theValue = $j(this)[0]["@value"];
var theId = $j(this)[0]["@name"];
select.append("<option value='" + theId + "'>" + theValue + "</option>");
});
select.children(":first").attr("selected", true);
}, selectBox)
回答2:
This is what I did, and it also worked fine:
$.ajax('URL', {
myCustomControl: selectBox,
myCustomVariable: 'teste',
data:
{
myData: 1
},
success: function (data, textStats, jqXHR) {
myFunction(data, textStats, jqXHR, this.myCustomControl, this.myCustomVariable);
}
});
You can add controls and variables to the parameters of your ajax call.
回答3:
Put this into your $.ajax parameters.
invokedata: {
data1: "yourdata",
data2: "moredata"
}
In the success function use it like this
this.invokedata.data1;
this.invokedata.data2;
Your $.ajax call and the success function must also be a part of the same object. Put your functions in an object and define them like this
function myObject {
var getImage = function(..) { }
var loadImagesInSelect = function(..) { }
}
回答4:
this
is Out of Scope
Just so you (or anyone else) understand(s)1, the reason that this
was undefined in loadImagesInSelect()
in your original example was because that function was under a different scope, and scopes don't "cascade" like that2.
When you specified a "context" of selectBox
in your AJAX call, it set the context (this
) for the functions given to "success" and "error". (It just so happens that they were both anonymous functions.) At this point, this
is defined in both of these functions, as the value of selectBox
. Now, in the function passed to "success", you call loadImagesInSelect()
. When you call a function, it creates a new scope. In this scope, this
will be window
in non-strict mode and undefined
in strict mode.
Put Graphically (in Strict Mode3):
// this = window (global scope)
$j = jQuery.noConflict();
function getImages(urlValue, selectBox) {
// this = undefined (function scope level 1)
$j.ajax({
type: "GET",
url: $j(urlValue).val(),
dataType: "jsonp",
context: selectBox,
success: function(data) {
// this = selectBox (function scope level 2)
loadImagesInSelect(data);
},
error: function(xhr, ajaxOptions, thrownError) {
// this = selectBox (function scope level 2)
alert(xhr.status);
alert(thrownError);
}
});
}
function loadImagesInSelect(data) {
// this = undefined (function scope level 3)
var select = $j(this);
select.empty();
$j(data).each(function() {
var theValue = $j(this)[0]["@value"];
var theId = $j(this)[0]["@name"];
select.append("<option value='" + theId + "'>" + theValue + "</option>");
});
select.children(":first").attr("selected", true);
}
$.proxy()
is Redundant
The use of $.proxy()
in your updated code is redundant. You use $.proxy()
to get this
to the function that was formerly called loadImagesInSelect()
, but you moved that function up into "success" anyway (instead of calling it from within "success"). It already has access now to the value of this
specified by "context".
You could remove the $.proxy()
wrapper around your "success" function in your updated code and it would still work.
I know it's been years since you asked your question, but I hope this helps.
- I hope this doesn't come across as condescending; it's not meant to be.
- At least, not when you call a function, and not with context. If you define a function within a function (i.e. a closure), then any variables in the outer function will be available in the inner function. However, the outer function's context (the
this
variable) still isn't available in the inner function.
- Replace
undefined
with window
for non-strict mode.
- Or the native
Function.prototype.bind()
in ECMAScript 5.
回答5:
You can use indexValue attribute for passing :
var someData = "hello";
jQuery.ajax({
url: "http://maps.google.com/maps/api/js?v=3",
indexValue: {param1:someData, param2:"Other data 2", param3: "Other data 3"},
dataType: "script"
}).done(function() {
console.log(this.indexValue.param1);
console.log(this.indexValue.param2);
console.log(this.indexValue.param3);
});