2017-04-20 192 views
1

下面的代碼將返回從innner函數到父函數displayButton()的布爾值嗎?在動態CRM中單擊按鈕時會調用父功能。該函數應該返回一個布爾值,具體取決於是否選擇了一個大小寫,並且所選擇的是活動還是解析。將內部函數的返回值返回父函數-javascript,動態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["[email protected]"]; 
         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

號如果你想訪問你的異步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["[email protected]"]; 

       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 
      } 
     }); 
    } 
} 

在上面的代碼中傳遞的函數是匿名的 - 您應該將其分開並命名。

+0

這也不起作用。 isActive變量包含值true或false,但不會向父函數返回true或false。我寫它爲 if(isActive){ return true; } else { return false; } 這不會返回true或false到displayButton函數。 – Dinoop

+0

它不會像你期望的那樣工作。這就是爲什麼我的答案和你的問題的其他答案都是**否**:你不能將你的異步請求的結果返回給你的父函數。如果你想使用你的內部函數的結果,你必須使用回調。如果'displayButton'本身不是父函數,也有父函數,那麼最初將回調傳遞給'displayButton',然後傳遞給'getCaseState'。如果'displayButton'是父函數,那麼你已經在使用'isActive'結果,並且不需要使用'return true'。 –

+0

displayButton是父函數。我返回isActive通過編寫: getCaseState(關於Id,函數(狀態){0} {0} {0}} is isctive = state ===「Active」; return isActive }); crm功能區上的按鈕取決於displayButton返回值。但即使解決了案例,該按鈕也正在顯示。如果case解決時isActive爲false,則不應顯示該按鈕。 – Dinoop

0

簡短的回答是沒有。內部函數被定義並分配給req.onreadystatechangedisplayButton()從不調用內部函數。所以它不會在這種情況下執行,因此不會返回一個值。

也許這可能是一個很好的挖掘更深入的功能在JS:https://www.w3schools.com/js/js_function_definition.asp

+0

謝謝。我怎樣才能編輯它來返回值取決於大小寫是否有效? – Dinoop

0

首先你粘貼了太多的代碼。這是堆棧溢出,你應該提供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;  
} 

我不想改變你的整個代碼,因爲你粘貼的方式太多了,但我敢肯定,你有這個想法。正如另一個答案中所建議的那樣,您應該將您的調用函數移至帶回調的單獨函數中,並在此回調中分配您的「結果」。回調將同步運行,因此該函數將返回具有適當值的「結果」。