dojo style developement - javascript

I'm having difficulty wrapping my head around dojo style of coding. The reason I am drawn to it is because of its class style coding. I have done AS developement and some java so it makes sense to me to be drawn to it. I have done some jquery style DOM work but I require a more framework based setup for a project I'm starting.
My question is should I be creating everything as classes with the declare and then requiring them when needed. Or could I write closure type functions with namespaces just like regular javascript modules. I'm confused.
Example I want to have a group of methods that take care of managing data. Then I want to have another collection of methods that handle special ajax calls. Would I create a class with declare for each of these groups of methods, in separate js files. Then in my app.js which is my application class where I'm handling the initialization of all my classes, would I require both those classes before dojo.ready(){}
then once the ready method is called I can start to use those classes.
Can someone set me straight here before I dojo out.
Does require make a load request for that js file and if so do you always have to use the ready method. If so is it best to require a bunch of your classes up front at the start of your application initialization.

Technically for what you're wanting to do, you could go either way - using dojo.declare or simply creating an object with function members. I'd be inclined to do the latter, since dojo.declare's elaborate inheritance considerations will be total overkill that you won't be making use of in this case, and it doesn't generally make sense to be instantiating anything when you just want to group some utility methods together.
For modules that simply group utility methods together, I'd be inclined to do something along these lines:
dojo.provide('my.utils');
my.utils = {
doSomething: function(){
/* do something... */
},
doSomethingElse: function(){
/* do something else... */
}
};
RE loading, if I'm reading you right, then yes, you have the right idea. In your web page, you would dojo.require(...) the modules your page requires (perhaps just one, if you have all your other dependencies further required within it). Then, any code in the page that expects these modules to be loaded should be within a function passed to dojo.ready. This ensures that even in cases where modules are asynchronously loaded (i.e. using the cross-domain loader), your code will still work. dojo.ready specifically waits for (1) the DOM to be ready and (2) all dojo.required modules up to that point to be loaded.
Note that within modules themselves, you do NOT need to enclose code in dojo.ready for the sake of waiting for dojo.required modules to load; this is figured out by the loader automatically. (However, if some logic in your module needs to wait for the DOM to be ready, you would still rely upon dojo.ready.)
I've written more about dojo.ready in the past; maybe it'll be a helpful read: http://kennethfranqueiro.com/2010/08/dojo-required-reading/

Related

Dynamically removing angular.module()

Is there a way to remove angular.module('SomeModule') dynamically?
This because I need to load and unload modules from a page in a tab-container.
This is based on Scott Moss' concept of where every single component is seen as a separate app on Frontendmasters.com.
I can get the module object by
angular.module(name)
Which returns an object respectively, but there I miss a clear way of clearing the references to this object. Has anyone solved something like this yet?
Template: http://plnkr.co/edit/8hK3lYjE7f06XtdHgNwL?p=preview
It sounds like you might be trying to optimize for something that doesn't exist.
First, there does not appear to be any documented way to remove modules. The reasons seem to be covered in the docs. In there you will find this statement (emphasis mine):
The modules can be loaded in any order (or even in parallel) because modules delay execution.
In that sentence it doesn't specify for how long the delay is but later we get this snippet (again, emphasis mine):
Because modules do nothing at load time they can be loaded into the VM in any order and thus script loaders can take advantage of this property and parallelize the loading process.
Put together, it sounds as if even with multiple of multiple modules, you won't notice a load on your site because the module will only be loaded when it is needed therefore removing modules is not a process that should ever need to be done.

Can/will AMD modules load in-between in-line script tags?

For reasons that aren't relevant to the question, my coworker needs to load a script that uses the Universal Module Definition pattern. Our environment usually has an AMD tool loaded, but for more irrelevant reasons, my coworker needs the script to define a global rather than registering a module through AMD. The approach that is currently checked in on their branch is something along the lines of this:
<script>
var backupDefine = define;
define = null;
</script>
<script src="../path/to/some/script/using/UMD.js"></script>
<script>
define = backupDefine;
backupDefine = null;
</script>
My question is: Is this a horrible idea? Is there a guarantee in the way browsers load scripts from script tags that will ensure nothing other than loading the UMD-based script will happen between undefining define and restoring define? We have a very large, very heavily async asset load primarily based around AMD modules, so what I am concerned with is an AMD module attempting to define itself in that intermittent state where define is currently not defined.
So long as UMD.js in no way modifies the scripts in the DOM, those scripts are guaranteed to execute in the order that they're authored in before any asynchronous callbacks that may have been queued before the first script executes.
I see this as a bad idea and spec breaking even if the case where define is always necessary is rare or even non-existent due to <script> load order considering your case. In an AMD environment, define, require and the like should basically be treated as first class keywords since their goal is to help you to remove globals.
Realistically, you're treading into undefined behavior as far as I can tell and writing code that is hard to maintain. You're relying on a tricky case with a spec where you have to undefine something and them immediately redefine it hoping that nothing tried to use it in the mean time. I'd say that that's "unsafe".
If you really need this to happen, I'd comment and document it heavily to make sure a future developer doesn't misunderstand what you're doing. However, I would say the better course of action is to rewrite the UMD.js file so that you export your global your own way. Rhetorically, why are you trying to use UMD if you don't want it to UMD things?
You're writing this module to support AMD through UMD but then you say that you don't want it to be used by AMD. Rewrite the file to just export to the global and avoid messing with define before you accidentally conflict with an additional library that does something tricky with define.

What is exactly define(function(require){...}) in JavaScript

I understand that define is used to define a module, and function is an anonymous function, but what does the argument 'require' in the function hold?
If I write anything in define(function(require){...}), when will this be called? How to give a call to his anonymous function?
Please help, I am new to advanced JS.
This is part of the requireJs api, it's not vanilla JS.
You can see the full docs in here:
http://requirejs.org/docs/api.html#define
"require" in the above example is actually the "require" code, this pattern allows you to require a JS and, than only when loading the JS is completed, load yet another dependency, but do so in the scope of the previously required file.
At large, this pattern allows you to break your app into multiple small JS files, and load them in an async way to speed up the loading process of web pages.
Some would argue that this is all going to be less needed when SPDY and HTTP2 are going to be more widely used. In any case, this is surely promotes a better modularity in the code design.

How to dispatch events globally and inside requireJS objects?

I am looking for a way to dispatch events globally and inside requireJS modules using javascript or jquery.
I would like to be able to say within my js files:
dispatchEvent(myCustomEventWithSomeData);
and then in some other part of the application add a listener like so:
addEventListener(“type Of Event”, executeThisFunction);
is this possible using jquery? Or any other means? And will a potential solution work within requireJS modules which are not global javascript objects?
Also, How can I create an event that bubbles. So that if I want an event to execute only in a specific section of the code it is not dispatched globally?
Yes, this is something I typically setup very early within my own applications. Now, how you deal with your events is going to be very dependent on what library or techniques you decide to use, but the core concepts will remain the same.
Personally, I think PostalJS is the cock of the walk, so I'm going to use that as an example here. I'm not going to include too much code because it would be mostly ceremony and boilerplate, but I hope you'll get the idea.
One, you'll want to create something like a global App object for your events to rest on. Overall this is a good practice when modularizing your JS code - you'll want something which acts as a broker between modules. It can be very plain and basic:
define(function() {
var App = {};
return App;
});
Now, this module should be loaded into something which begins to populate it. You can get away with not doing this, for a while, but I find eventually circular dependencies tend you bite you in the ass. So I recommend including this in something akin to your "main" module. From there, include your event system and add it to App.
define(['app', 'events'], function(App, Events) {
App.events = new Events();
});
Now you have a nice, lightweight object you can include in other modules which shares the same Events object. So lets say you have a sidebar:
define(['app'], function(App) {
// User has clicked the sidebar
App.events.publish('sidebar.clicked'); //
});
And, oh I don't know, perhaps clicking the sidebar makes a dinosaur appear, so in your dinosaur module, you'd listen/subscribe by doing the following:
define(['app'], function(App) {
App.events.subscribe('sidebar.clicked', showDinosaur);
});
Having a lightweight object you can share between modules I've found is key to a successful modularized JS architecture. I use this in my own projects as a global object store, a container for my WebSocket messaging layer, and other things I don't want to need to explicitly include individually in each module.

How to remove JS logging calls in our prod build of our mvc3 web app?

We've got a lot of calls to our logging methods (that just wrap console.log) all throughout our JS in our MVC3 web app and I'd like to remove them from the JavaScript when we build our test and production builds.
Currently we're using the bundling and minification nuget package to bundle and minify our JS into one big minified file but I'd like to have it rip out the calls to the logging methods as well.
We do have a mechanism in place that replaces the logging methods with empty functions so they won't do any work in production, but they are still called and various arguments are passed in. On top of this, there are "large" strings that are passed and those could be removed, reducing filesize.
The ideal solution in my mind would be to somehow parse the JavaScript and detect / remove the calls to those methods. Preferably in some sort of JavaScript engine and not just a regular expression.
Either way, I just want my calls to my logging methods removed in the final JavaScript that is served up in production. Does anyone know how I'd accomplish this additional minification?
Yep, the IBundleTransform interface was designed for this scenario. In RC bits here's what we envisioned:
new Bundle("~/bundles/js", new LogRemoverTransform(), new JsMinify());
Basically, you construct a bundle and chain two transforms, first stripping your log methods, and then running through normal minification. Prior to RC, you would have to do the composition inside of your IBundleTransform.
You could write your own implementation of IBundleTransform that first removes calls to your logging methods via a regular expression and then calls the default bundling and minification functionality. As long as your calls are fairly simple, it shouldn't be hard to come up with. It might get tricky though, depending on how you call your logging code.
For example, it'd be fairly hard (for me) to build a regex that would catch the entirety of a logging call like this:
NS.log(function () { return "this is going to be hard to parse"; }());
But, as long as you don't log like that, it shouldn't be a difficult regex to write.

Categories

Resources