The existing answers cover most points well; I'll expand the problem to consider whether or not the dialog's size will depend on the data returned (as well as mentioning a pet-peeve about meaningless spinners).
Statically-Sized Dialog
If the size (and final position) of the dialog is known/calculated at the point of clicking, and will not depend on the retrieved data, then musefan's answer of opening the dialog immediately is the best/simplest. You know you are going to open it; you know where and how big it will be: so open it immediately. As museman also suggests, include some form of "Loading..." message so the user knows that the real content will (should) follow shortly.
Exactly what the loading message says, and where it should appear is probably as much a matter of personal preference and/or existing styling as anything else. My starting point would probably depend on the "expected" response time of the data-retrieval request:
In a corporate environment, running over an internal network, where most of the time you expect "close to immediate" responses (roughly the 0.1 seconds or so mentioned in maxathousand's answer), then I'd probably go with a somewhat discrete "Loading..." message towards the top-left corner. Most of the time the users won't get a chance to see it, so you don't want it "in their face": you just need something for the (hopefully rare) times when the response is slower than normal.
If you are running over the public internet, where expected response times could easily be noticeable, then I'd probably favour a more centrally-placed message. Users are more often going to have a chance to see the message, so put it at the centre of their focus so they know "something's happening".
Dynamically-Sized Dialog
If the (final) size of the modal dialog is going to depend on the amount/nature of the data received, then a different approach is needed: ideally, you don't want a large, "about the right size dialog" to appear, only for it to change its size (and possibly position) a short while later.
You would still want an (almost) immediate feedback that the request has been started, but – because you don't yet know the size of the "real" dialog – you shouldn't use that to show the feedback. If you are going to "dim" the main page while the dialog is shown, then dimming it immediately is probably a good idea. Showing a spinner of some kind (but see my "pet peeve" below), or just a "Loading..." message in the middle of the screen would also be helpful.
In this case, the "extra complication" suggested by maxathousand probably is worth it: you don't want to distract the user with a spinner/message if it's replaced by the real dialog almost immediately. I'd consider the following steps:
If used, dim the main page as soon as the button is clicked: immediate acknowledgement.
Start the "tenth-of-a-second" timer: if the full response isn't available after a short pause, display a spinner and/or "Loading..." message.
When the data is available, remove the spinner/message (if shown) and display the modal dialog with whatever size has been calculated from the data.
Pet Peeve: (Meaningless) Animated Spinners/Progress-bars
Musefan suggests "it might be worth making the loading indicator static" if "it's only going to be visible for a short time". Part of me would like to take this advice a step further: make it static unless there's positive, ongoing feedback from the server.
Originally, in desktop programs, a progress-bar would show how much of a task had been completed: if you were copying a number of files, the progress-bar might advance with every file copied. (Ideally, it would advance as a certain amount of data was copied, so a single large file wouldn't make it look like the process had stopped.) For "open-ended" tasks (e.g. downloading a file of unknown size), you might have to reset the progress-bar part way through (or use a different format, e.g. a spinner). However, in either case, the key thing that makes them useful is that their advancement is driven by "things happening" – they showed the user that the process was "still working".
However, many/most spinners in modern web-apps are not driven by progress in the task being performed: they are animated locally in JavaScript or as an animated GIF. However much it makes the user think something is still happening, most of them do not actually convey any information – you could unplug your network cable and the spinner will happily continue to spin!
Of course, given the ubiquity of spinners these days, even if most are meaningless, not having one is likely to make most users think "the internet has crashed". It's probably too late to only use them when true progress (or a "heartbeat") is available.