下面的代码会将内部函数的布尔值返回给父函数displayButton()吗?单击动态CRM中的按钮即可调用父函数。该函数应返回一个布尔值,具体取决于是否选择了一个案例并且所选择的是处于活动状态还是已解决。
//function called on click of a button in ms crm.
function displayButton()
{
var Obj = parent.Xrm.Page.getAttribute("regardingobjectid");
var ObjValue = Obj.getValue();
//parent.Xrm.Utility.alertDialog(" Value: " + ObjValue);
if (ObjValue == null)
return false;
//else
// parent.Xrm.Utility.alertDialog(" Hi");
var EntityType = ObjValue[0].entityType;
var Guid = ObjValue[0].id;
var id = Guid.slice(1, -1);
//parent.Xrm.Utility.alertDialog(" Guid: " + id);
//Checking if regarding field is selected a case lookup value
if (EntityType == "incident")
{
var req = new XMLHttpRequest();
req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(" + id + ")?$select=statecode", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function ()
{
if (this.readyState === 4)
{
req.onreadystatechange = null;
if (this.status === 200)
{
debugger;
var result = JSON.parse(this.response);
//checking if selected case is active or resolved.
var statecode = result["statecode"];
var statecode_formatted = result["statecode@OData.Community.Display.V1.FormattedValue"];
if (statecode_formatted == "Active") {
return true;
}
else if (statecode_formatted == "Resolved")
return false;
else {
return false;
}
}
else
{
parent.Xrm.Utility.alertDialog("Zero");
}
}
};
req.send();
}
else {
return false;
}
}
答案 0 :(得分:0)
简短的回答是否。内部函数被定义并分配给req.onreadystatechange
。 displayButton()
从不调用内部函数。因此它不会在此上下文中执行,因此不会返回值。
这可能是对JS中函数的深入挖掘:https://www.w3schools.com/js/js_function_definition.asp
答案 1 :(得分:0)
没有。如果要访问异步XmlHttpRequest
返回的值,则需要将逻辑放在if (this.status === 200)
范围内或提供回调。
由于此行中的XMLHttpRequest
参数,您的true
是异步的:
req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(" + id + ")?$select=statecode", true);
要提供回调,请将代码分成两个函数:
function getCaseState(id, callback) {
var req = new XMLHttpRequest();
req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(" + id + ")?$select=statecode", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var result = JSON.parse(this.response);
var statecode = result["statecode"];
var statecode_formatted = result["statecode@OData.Community.Display.V1.FormattedValue"];
callback(statecode_formatted);
}
}
};
req.send();
}
然后拨打getCaseState
,将事件id
传递给您,并在请求准备好后调用函数:
// called on click of a button in CRM.
function displayButton() {
var regarding = parent.Xrm.Page.getAttribute("regardingobjectid").getValue();
var entityType = regarding[0].entityType;
var regardingId = regarding[0].id.slice(1, -1);
// Check if regarding is an active case.
if (entityType == "incident") {
getCaseState(regardingId, function(state) {
var isActive = state === "Active";
if (isActive) {
// TODO
}
});
}
}
上面代码中传递的函数是匿名的 - 您应该将其进一步分开并命名。
答案 2 :(得分:0)
首先,你粘贴的代码太多了。这是Stack Overflow,你应该提供Minimal, Complete, and Verifiable example 在不更改代码的情况下执行此操作的唯一方法是将请求更改为已建议的同步,并将结果分配给在回调之外定义的某个变量。这样的事情:
function displayButton(){
var result = false; //or true, depends what you want as default
//some code
//change it to synchonous request!!
var req = new XMLHttpRequest();
req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(" + id + ")?$select=statecode", false);
//...
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
//ommiting more code to get to the clue
//...
//...
if (statecode_formatted == "Active") {
result = true;
}
else if (statecode_formatted == "Resolved")
result = false;
else {
result = false;
}
}
}
};
req.send();
return result;
}
我不想改变你的整个代码,因为你粘贴了太多的代码,但我相信你已经有了这个想法。正如另一个答案中所建议的那样,你应该将你的调用函数移动到一个带回调的单独函数,并在此回调中分配你的“结果”。回调将同步运行,因此该函数将返回具有适当值的“结果”。
答案 3 :(得分:0)
您的 XMLHttpRequest 在此处异步。因此,您无法立即获得响应,因此执行不会立即结束。
我使用
解决了此问题setTimeout(function () {
},550);
我认为您可以按照以下方式尝试。
我所做的更改是将 XMLHttpRequest 保留在单独的函数中,即 getResult(id)并从父级调用该函数功能,即 displayButton()。
并从子功能中返回返回值,我正在将该布尔值设置为Global变量,即 var boolValue; >
在父函数返回值之前,我正在等待5.5亿秒 ,以便异步执行结束。
下面是代码段。
父项功能
var boolValue;
//function called on click of a button in ms crm.
function displayButton() {
var Obj = parent.Xrm.Page.getAttribute("regardingobjectid");
var ObjValue = Obj.getValue();
//parent.Xrm.Utility.alertDialog(" Value: " + ObjValue);
if (ObjValue == null)
return false;
//else
// parent.Xrm.Utility.alertDialog(" Hi");
var EntityType = ObjValue[0].entityType;
var Guid = ObjValue[0].id;
var id = Guid.slice(1, -1);
//parent.Xrm.Utility.alertDialog(" Guid: " + id);
//Checking if regarding field is selected a case lookup value
if (EntityType == "incident") {
getResult(id);
setTimeout(function () {
if(boolValue == true || boolValue == false)
{
return boolValue;
}
}, 550);
}
else {
return false;
}
}
子功能
function getResult(id)
{
var req = new XMLHttpRequest();
req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(" + id + ")?$select=statecode", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var result = JSON.parse(this.response);
//checking if selected case is active or resolved.
var statecode = result["statecode"];
var statecode_formatted = result["statecode@OData.Community.Display.V1.FormattedValue"];
if (statecode_formatted == "Active") {
boolValue = true;
}
else if (statecode_formatted == "Resolved")
boolValue = false;
else {
boolValue = false;
}
}
else {
parent.Xrm.Utility.alertDialog("Zero");
}
}
};
req.send();
}
这种方式解决了我的问题。