AngularJS special scope arrangement - javascript

So I have an interesting situation. I have an angularJS app broken into several different modules. This is done so the different pieces can be as generic as possible and eventually reused. One of these modules is a uiTemplate module which handles very common tasks dealing with the ui such as expandable/collapsible sections. Is it possible to place other modules "below" the uitemplate module so that when they emit events they pass through the uitemplate? The goal is to be able to do this without the uitemplate module knowing anything about the other modules, or in other words, without the uitemplate having any "hardcoded" dependencies on the other modules. If I could dynamically tell uitemplate its dependencies that would be ok, I would just like to avoid putting application-specific code into the module. Possible ideas?

It would look something like this:
<div ng-controller="ParentCtrl">
<div ng-controller="Child1Ctrl"></div>
<div ng-controller="Child2Ctrl"></div>
</div>
However, if you're talking about sharing just UI elements, it might make more sense to make them directives. They get compiled differently and you can call them from any view.

Related

Why is project files organizing as they are in React?

I've noticed that react projects tend to be organized like this,
/src
/actions
userActions.js
settingsActions.js
/components
userComponent.js
settingsComponent.js
/containers
userContainer.js
settingsContainer.js
/reducers
userReducers.js
settingsReducers.js
coupled on type rather than functionality like,
/src
/user
userActions.js
userComponent.js
userContainer.js
userReducers.js
/settings
settingsActions.js
settingsComponent.js
settingsContainer.js
settingsReducers.js
Why is that? To my understanding React is good in part because it couples css, html and js together instead of having them separate. Why not do it with the file structure as well?
There is no one true way to organize your files and directories, it varies with the opinions. But people still wonder what the best method for organising the code is.
I usually prefer the structure where containers, components, actionCreators, services and reducers are segregated. Whichever pattern you are following, you can make it more and more granular once your codebase scale up. I hope you are familiar with the idea of Presentational vs. Container components.
In the first pattern, components/ just hold the dumb stateless components that just takes props. This pattern very well support the concept of reusability. When you develop a large application, it happens quite often that you need to create a component that you definitively know you won’t reuse anywhere else, but you need it.
The containers/ have the stateful components which make API calls. Same way, if you are using redux in your application, many people tries to follow the ducks pattern where you define all the reducers in a single directory along with your root reducer, just to make things more granular and easy to access, and you don't have to jump between files to create an action.
This is just my perspective, but as I mentioned earlier, it totally depends on the use case of an application and also the opinion of the one who develops it. An alternative is to organize files by functional area as you mentioned in your second directory structure, with folders like users and settings kind of functionalities. This organization style starts off deceptively simple. But inevitably you end up with a folder common where you store very basic and common components like button, which are used all over your app, eventually you will end up with common/components and common/containers, but at one level deeper.
In short, start simple with whichever structure you want, you will eventually make it finer and finer with your use case and scale.

Webpack: Is duplicate module loading inefficient?

From my understanding, webpack (and other similar bundlers) ensures that if the same module is required across multiple parts of the app:
That code will only be loaded once
Each time the same module is required, a new instance is created, rather than all sharing the same scope
Firstly, are my above assumptions correct? If so, is it bad optimisation to have multiple instances of the same module being created?
In my example I am creating an app that will be using ThreeJS. This is a rather large library. Many of the modules in my app will want to require this library.
Is it bad practice to keep on requiring a library like this? Or should I be passing a single instance from module to module instead of requiring multiple times?
I'd be interested to know if there are any common patterns for dealing with this, if it is indeed an issue.
This assumption:
Each time the same module is required, a new instance is created,
rather than all sharing the same scope
is wrong for two reasons:
Whether an instance is created or not, will depend on what is returned by the required module (it could return nothing).
Even if the module initialises an instance, only one will be created, as the code in the module is only run once.
With that said, requiring the same module multiple times should have no impact in performance.

How do I efficiently declare AngularJS module dependencies?

I have an Angular application which is going to become quite large. For the sake of clarity, I opted for splitting it into different modules, one for each application area. I'm adding components strictly related to an area to the corresponding module, and shared components to an additional common module. All these modules are in turn loaded by a unique main module, that depends on all of these and basically represents the application as a whole.
Now, it turns out that many of the areas need internationalization, so each area's module depends in turn on a translation module to have its string localized. But when I put it all together by means of the main "aggregator" module the translate module ends up with being loaded multiple times, with only one instance actually used.
For instance, let's say my application has the following areas:
Main dashboard
Settings
Documentation
Support
Corresponding modules are declared as follows:
angular.module('app.mainDashboard', [translate]);
angular.module('app.settings', [translate]);
angular.module('app.settings', [translate]);
angular.module('app.support', [translate]);
and the main module looks like this:
angular.module('app.main', [app.mainDashboard, app.settings, app.settings, app.support]);
This approach definitely works, but I bet there is a better way to achieve the same result without repeatedly loading the same dependency. Or perhaps my initial module splitting approach is awkward by itself and in turn it leads to this other inconvenient.

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.

requireJS : How to structure Javascript for an entire site?

I have 3000+ lines of javascript that I need to get into a sensible/maintainable structure. I have chosen to use requireJS as it has been recommend to me by a few people. I have a bunch of variables that are used throughout the application and need to be available everywhere. I also have a bunch of functions that need to be available everywhere. Apart from these two dependencies most of the code can be divided off into their own modules.
I am having trouble understanding how to manage my main variables so that if one module of code makes changes to the variables the rest of the JS modules will see that change. I think I need to see a few examples that demonstrate how requireJS is intended to work on a larger scale that the examples in the documentation.
If anyone is an experienced requireJS user I would love the hear your tips!
The whole point of RequireJS is to avoid the need for these global variables and global functions.
Can't you wrap those globals into a module, then depend on it in your other modules?
For example, a RequireJS modularized Dojo may be something like:
dojo/cache module
dojo/string module (requires dojo/cache)
dojo/date module (requires dojo/string)
dojo/cookie module (requires dojo/string)
:
:
dojo module (requires everything above, make them all into sub-objects, say, e.g. dojo.cache, dojo.string, dojo.date etc.)
user module #1 (requires dojo)
user module #2 (maybe only requiring dojo/string)
RequireJS gives you better options for encapsulating modules, but it doesn't change Javascript itself at all. As a transition strategy, you can still define your globals inside the function block. Depending on the module that contains these definitions will ensure that it has run before the dependent modules.
Next step would be to assign those methods to an object other than window, and then use that object through the variable received from RequireJS module dependency.
Hopefully by the time you've done this, you might have some insight into a cleaner solution. I refactored (and still am) a single-file project into several files, including optional plug-ins, although I did most of it before adding RequireJS to the mix.
See the RequireJS documentation:
Defining a module
Definition Functions with Dependencies
If the module has dependencies, the first argument should be an array of dependency names, and the second argument should be a definition function. ... The dependencies will be passed to the definition function as function arguments
define(["./cart", "./inventory"], function(cart, inventory) {
// ...
return { ... };
}
);
So I think you can define() your main module like all other modules and make the submodules depend on that main module. Then the module object is passed as an argument to the definition function of a submodule. You don't have to use global variables.
If you want to share information between modules, attach the information to the module object, and have the other modules rely on that module, and check its property.
If you have existing code, you can assign to window.x to provide a global x while you are cleaning it up.

Categories

Resources