在Javascript中使用委托(例如使用XMLHttpRequest AJAX请求)



我有一个AJAX页面,它从GET返回一些数据。所有的好。我试图从Javascript调用它,以响应用户更改名为ProductCode的选择元素的值。我来自c#世界,如果我的一些术语有点偏离。

Javascript:

function ProductCodeChange()
{               
try
{
elProductCode = document.getElementById("ProductCode");
ProductCode = elProductCode.value;

var AJAX_MAGICTOKEN = "773d8626-6b78-4055-bf8b-4fbbaa725550";
url = "AJAX_GetData.php?";
url += "MagicToken=" + AJAX_MAGICTOKEN + "&";
url += "Query=GetProduct&";
url += "ProductCode=" + ProductCode;

httpxml = new XMLHttpRequest();
httpxml.onreadystatechange = PopulateProductCode(httpxml);
alert(">httpxml.open");
httpxml.open("GET", url, true);
httpxml.send(null);
}
catch (e)
{
alert(e.message);
}
}

function PopulateProductCode(httpxml)
{
try
{
alert(">ProductCodePopulate");
if (httpxml.readyState == 4 && httpxml.status == 200) 
{
data = httpxml.responseText;
alert(data);
}
else
{
alert("readyState: " + httpxml.readyState.toString());
alert("status: " + httpxml.status.toString());
}
}
catch (e)
{
alert(e.message);
}
}

HTML:

<select id="ProductCode" name="ProductCode" onchange="ProductCodeChange();">
<option value="AP1A" >Annual Licence</option>
<option value="AP1M" >Monthly Licence</option>
</select>

我已经配置了XMLHttpRequest对象,当onreadystatechange事件被触发时调用PopulateProductCode。我有相当多的工作要做的数据返回,并希望有一个单独的函数调用时,XMLHttpRequest返回数据。

如果我的c#世界,httpxml.onreadystatechange = PopulateProductCode(httpxml);行设置httpxml对象与一个委托,一旦它的就绪状态发生变化调用。但是,在执行上面的代码时,事件的顺序是:

alert(">ProductCodePopulate");
alert(">httpxml.open");

所以我的委托在GET请求被发送之前被调用。

我是否完全误解了这个对象的工作原理?我怎样才能实现我想做的(即保持功能在一个单独的功能)?

如果你能坚持香草Javascript在你的答案,那将是伟大的。我还不熟悉JQuery。谢谢。


编辑:另一种选择是:

httpxml.onreadystatechange =
function()
{
if (this.readyState == 4 && this.status == 200) 
{
data = httpxml.responseText;
alert(data);

}
}

这个使正常工作,直到返回数据才执行。从下面@James的回答来看,第一个版本会立即执行,但上面的版本不会。我不明白这两者之间有什么区别,除了第二个没有函数名。它们肯定是一样的,但有一个版本是无名的?为什么在处理上有差异?

在Javascript中,这一行httpxml.onreadystatechange = PopulateProductCode(httpxml)首先使用httpxml参数调用PopulateProductCode,并将其返回值分配为事件处理程序,以便在就绪状态发生变化时使用。

最简单的方法是将对PopulateProductCode的调用封装在一个匿名函数中。

httpxml.onreadystatechange = () => PopulateProductCode(httpxml);

我建议将方法更改为较新的实现。fetch API。它返回一个promise。提高代码的可读性,是现在更好的方法。

建议阅读:

获取API与XMLHttpRequest

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

最新更新