-->

Dojo/request undefined despite require

2019-09-17 20:03发布

问题:

In a script associated with an Orchard view I try to post an AJAX to server with dojo.request.post function. However, I only get esri/request, dojo/request is undefined. I call the request outside the function where the require statements reside, but there's no problem with other required packages as long as I use them in correct format. Dojo/request works in our other project, so I suspect Orchard of messing things up (the other project's dojo/request use is in a plain page, not in a view), though I would expect problems caused by it to surface earlier.

Important parts of the code:

require([ ... "dojo/request", ... ], function (... Request, ...) {
  //custom init function contents
})

function sendResults(featureSet) {
  //custom code processing the parameter, making uri, JSON and like
  dojo.request.post(uri, {
    //sending data
  })
}

My razor require part in the same file contains:

Script.Require("esri/JavaScriptApi").AtHead();
Script.Require("dojo").AtHead();

Those are defined in resourcemanifest.cs:

 manifest.DefineScript("esri/JavaScriptApi").SetUrl("http://js.arcgis.com/3.14/");
 manifest.DefineScript("dojo").SetUrl("//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js");

The error I get when I try to run the code:

TypeError: dojo.request is undefined

I've tested it in FireBug and confirmed that dojo/request doesn't exist (the same for variants, like dojo/Request), only esri/request is a function, but it has no post method.

I'm stuck here. Google search lead to "plains of sheer desperation" (page 5+) with no useful output and my co-workers don't know. Does anyone know why I can't see dojo/request and how to get it?

回答1:

As far as I'm aware, dojo/request does not export a global (as modern AMD modules generally shouldn't need to), so dojo.request would never work in any context.

The appropriate way to use AMD modules is to use them within the body of a require callback (or, even better, organize your own code in AMD modules as well, and use them within a define factory function).

require([ ... "dojo/request", ... ], function (... request, ...) {
  request.post(...);
})

Alternately, if you're certain dojo/request has been loaded by the time you want to use it, you could use single-argument require to reference it:

require('dojo/request').post(...);

However, this is typically not ideal and seen as a hack.

Perhaps the Introduction to AMD Modules tutorial would help to better understand optimal AMD usage.