I'm jumping off the deep end and starting to convert some apps to AMD style that were originally written in legacy dojo. One thing I've picked up about migrating to AMD is that the legacy practice of doing this:
<script type ="text/javascript"> var dojoConfig = {parseOnLoad: true}; </script>
in the HTML header section has been replaced by doing this:
ready(function() { parser.parse(); ..... }
down in the Javascript code. I never questioned this; I just did it. In my current work trying to migrate a legacy app to AMD, I ran into a maddening issue where my attempts to establish a listener event on a dojo form that had two radio checkboxes as choices:
// Event listener to enable/disable controls based on the input method chosen dijit.byId("frmEndMethod").on('change', function() { .... });
would always error out because dijit.byId() couldn't find the widget and thus, returned undefined. The code was within the ready(function() {...}); so it should have no problems finding it. In fact, I could type "dijit.byId("frmEndMethod")" into the console after page load and it does return the dijit. No matter what I tried, I could not get this to work. Then I reverted back the the legacy variable declaration in the header and commented out parser.parse() in my JS code.
Surprise, surprise- it loaded without error and the event now triggers. So what gives? Am I "wrong" to still use the dojoConfig variable with AMD style coding? I mean, it seems to work, which is the whole point but is there something I'm missing?
Steve
Hey Steve,
If you don't mind, I changed this into a question.
Tim
You did include in your require([ "dojo/parser"] and in your function the corresponding parser right?
i.e.
require(["dojo/parser"], function (parser) {
parser.parse();
No problem changing it to a question. I saw it as a discussion but no big deal.
Yes- I do have parser specified in my list of requires.
I believe it is the first thing you need to call before all the other dijits and widgets initialization.
There are many ways to setup the dojo config
you can use the legacy way like this
<script>
dojoConfig= {
parseOnLoad: false,
async: true
};
</script>
of use script tag
<script src="http://js.arcgis.com/3.13/ " data-dojo-config="parseOnLoad: false, async: 1">
</script>
Read more here:
In my code, when I was trying to use parser.parse(), it was my first line of code in my ready() function.
What is this ready function?. Can you share the code. It should be as Tim shown below require
Sorry- the ready function as in dojo/ready:
require([ "dojo/ready", "dojo/on", "dojo/_base/connect", "dojo/_base/event", "dojo/dom", "dojo/fx", "dojox/grid/DataGrid", "dgrid/Selection", "dojo/promise/all", "dojo/data/ItemFileReadStore", "dojo/store/Memory", "dojo/_base/array", "dijit/registry", "dojo/_base/declare", "dojo/dom-construct", "dojo/keys", "dojo/parser", "dijit/form/Button", "dijit/form/CheckBox", "dijit/form/DateTextBox", "dijit/form/FilteringSelect", "dijit/form/Form", "dijit/form/Select", "dijit/form/HorizontalSlider", "dijit/form/HorizontalRule", "dijit/form/RadioButton", "dijit/form/TextBox", "dijit/form/TimeTextBox", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojox/layout/ExpandoPane", "dijit/layout/AccordionContainer", "dijit/Menu", "dijit/MenuItem", "dijit/MenuSeparator", "esri/Color", "esri/geometry/Extent", "esri/geometry/webMercatorUtils", "esri/graphic", "esri/InfoTemplate", "esri/map", "esri/arcgis/utils", "esri/domUtils", "esri/dijit/Geocoder", "esri/dijit/HomeButton", "esri/dijit/BasemapToggle", "esri/dijit/Measurement", "esri/dijit/Popup", "esri/dijit/PopupTemplate", "esri/geometry/Point", "esri/SpatialReference", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleFillSymbol", "esri/symbols/PictureMarkerSymbol", "esri/layers/FeatureLayer", "esri/layers/GraphicsLayer", "esri/toolbars/draw", "esri/tasks/FeatureSet", "esri/tasks/GeometryService", "esri/tasks/locator", "esri/tasks/ProjectParameters", "esri/tasks/query", "esri/tasks/QueryTask", "esri/tasks/RouteParameters", "esri/tasks/query" ], function( ready, on, connect, event, dom, fx, DataGrid, Selection, all, ItemFileReadStore, Memory, array, registry, declare, domConstruct, keys, parser, Button, CheckBox, DateTextBox, FilteringSelect, Form, Select, HorizontalSlider, HorizontalRule, RadioButton, TextBox, TimeTextBox, BorderContainer, ContentPane, ExpandoPane, AccordionContainer, Menu, MenuItem, MenuSeparator, Color, Extent, webMercatorUtils, Graphic, InfoTemplate, Map, arcgisUtils, domUtils, Geocoder, HomeButton, BasemapToggle, Measurement, Popup, PopupTemplate, Point, SpatialReference, SimpleLineSymbol, SimpleMarkerSymbol, SimpleFillSymbol, PictureMarkerSymbol, FeatureLayer, GraphicsLayer, Draw, FeatureSet, GeometryService, Locator, ProjectParameters, Query, QueryTask, RouteParameters, Query ) { ready(function(){ parser.parse(); esri.config.defaults.io.proxyUrl = "http://dmc-arcgis/proxy/proxy.ashx"; esri.config.defaults.io.alwaysUseProxy = false; //etc..etc..etc.. dijit.byId("cboRdName").on('change', function(selection) { updateCrossStreetList(); closureProps['rdName'] = document.getElementById('cboRdName').value; closureProps['status'] ='CLOSED'; zoomToRoad(); }); }
Try to move the parser.parse outside the ready function. As per the doc dojo/ready — The Dojo Toolkit - Reference Guide it says, its has been replaced by AMD API. so you dont exactly need to use ready unless there is a special requirement.
I also see you are loading a huge list of objects in the require. try to avoid it, load only the ones you are going to use are used in Html. I understand you are migrating from legacy to AMD style. try to be more modulaized and divide the code into smaller modules and widgets. Hope it was helpful.
Instead of using dijit.byId, have you tried using registry.byId?