AngularJS module architecture - javascript

I am planning to create several modules in my company's application and I'm having trouble designing the architecture for the modules. I have done research and it seems like either you are supposed to use one module per page, or create a 'master' module that depends on all of your other modules. I don't like this approach because it means I have to load all of the javascript for every aspect of my application for every single page. That seems inherently wrong, but I also can't seem to figure out how to handle it the other way if I need to use one module in multiple places on a page. For example, I have a membership module that I have and I'm attaching to the header section of my web page. This would be intended for logging in, registration, and performing a 'forgot password' type workflow.
On another page dedicated to changing a password (from a reset link) the header is also present, but I want to include the password reset functionality in the membership module. I've read that one methodology of designing your application is by functionality/feature. I figured membership was an appropriate application of that, but now I'm not sure since I am having trouble applying the membership module more than once on any particular page.
Am I on the right track, or is there a preferred method for this? Should I have a separate module for the header and one for the rest of the page? Should I just bite the bullet and load everything? (I hope not...)
I should also note that this is an ASP.Net MVC application where we are still heavily relying on MVC for serving views and partial views. As such I wanted to use a render javascript section to dynamically load only the javascript necessary for that page to function. Is this a farce?
<header ng-app="membership">
//stuff for header membership functions
</header>
<div ng-app="membership">
//somewhere else that needs membership, outside of header
</div>

I personally like Mini SPAs (Silos) instead of full SPA. You can watch Miguel A Castro's video, and download the source at his website.
What it does is when a request comes in, it goes to ASP.Net MVC Route first. Then, Angular Route takes over the rest. It is a very slick design.
FYI: Angular 2 is right around the corner, so I went ahead and updated those to Angular 1.5 Compotent so that I can convert to Angular 2 easily later.
If you want, you can stop there. I went one step future, and use Strongly Typed Views using Matt Honeycutt's Building Strongly-typed AngularJS Apps with ASP.NET MVC 5 approach.
Then I implemented Angular Helpers like Axel Zarate's ANGULAR.NET – HELPERS FOR ASP .NET MVC 4.

On an Angular application, as it is a Single Page Application, yes, all your javascript must be loaded. It's the code of your application and it's necessary. That's done only once on first page load.
You're always on the same page, but on a different state.
One good approach is to define a master module who include all other modules. Those modules can also include other "sub modules" they need.
angular.module('App', [
'App.Membership'
// ...
// All others modules you need, including 3rd party modules
])
Then, on each module, you can define the different states associated and their controller
angular.module('App.Membership', [
// Module dependencies
])
.config(['$stateProvider', function($stateProvider) {
//State definition
$stateProvider.state('membership', {
parent: 'app',
url: '/member',
controller: 'MembershipCtrl',
template: '<ui-view/>'
});
}]);
You can also add a global controller to handle elements who are always present, like a header.
Hope this helps

Related

How to structure app with Angular JS

I am trying to learn Angular JS and use it in my web app project and am looking for some guidance as well as answers to specific angular js questions. Tech stack I am using is MySQL db, Java w/ Spring Framework, HTML/CSS/Bootstrap/JS, etc..
The purpose of the app is basically a "social media craigslist" where it will have:
1. User accounts
2. Ability to create a "newsfeed-esque" post (one "view")
3. Ability to create a sale post (separate "view")
4. A view for an "inventory"
5. A view for a "wishlist"
etc..
(note: Items 2-5 are accessed via a nav bar of sorts that sits on the left side of my page and the idea was to have the main section of the page switch the content based on what nav item you clicked.. more later..)
What I was doing was writing a bunch of Javscript code to make calls to my web services (grabbing static content to populate drop downs, sending user login info for logging in, etc..) and the < script > tags were growing and all of this was living in my index.html page and I thought it might make more sense to use something like Angular JS and structure it a bit differently and "modularize" the code so it wasn't a giant mess in index page. I was also doing some manual .hide() and .show() JS stuff so I thought that it also might make more sense to switch out the content using something like AngularJS instead of having maximum ONE .show() active at once and then having to do as many .hide()'s as I would need to, to manually switch out the content. This is sounding like a SPA (single page app) right?
I have researched AngularJS StackOverflow posts and looked at w3schools and other helpful websites but am having trouble with how to structure this and use best practices not only with code efforts but organizational as well.
1) Am I correct in thinking Angular would make the hide and show of content easier?
2) I would like to make each "feature" of my website have its own controller and have Controller1.js, Controller2.js, etc.. but do I need to have a
var app = angular.module('myApp', []); ...
line at the top of each controller or do I need something like a main controller with that in there only once and then a call to each controller from a main controller? Or is this not even how I should go about it? Thought process was again to modularize and avoid having one giant beastly file with all my JS logic in it.
3) I assume that I need to use the ng-route stuff (is this correct?) in order to do that hide and show of html content? (items 2-5 listed above) But in what file should that live? a javascript controller file? index.html? other?
4) I read you can only have one ng-view per application. Does that mean that you can only switch/change the content for ONE < div > / section of your web app, OR can you have multiple different divs being changed?
5) fyi - my current file structure is pretty much this.. is this how it should be?
-Java Resources (java code)
...
-WebContent
-img
-META-INF
-resources
-css (folder)
-js (folder with js files - controllers)
-WEB-INF
-lib (folder)
-views (folder)
-xx-servlet.xml
-web.xml
-index.html
-pom.xml
A lot of my questions are just because I am new to AngularJS and not seasoned in JS itself so am trying to better understand. Thanks for any and all help in advance.
First of all, if you want to use multiple views per app then you should use angular-ui-router module instead of angular-route module.
Now, we come to the file handling. So, for that you can make as much file as you can to define controllers, config, services and factories for the app. There are three ways of doing this.
The first one is putting var app = angular.module("MyApp",[]); in first file and defining controllers and services like app.controller('ctrl', ControllerFunction) in each of the other files below the first one. But, personally i don't prefer to use this way as you are exposing your app as a global variable here.
The second way is to create a main module in first file using angular.module('MyApp',[]) and in other files you can get it and define controllers using angular.module('MyApp').controller('ctrl', ControllerFunction). This is the safer way than the previous one.
The third way is to create a different module in each of the files and using all the modules in a single main module as dependencies. Like below
in one file
angular.module('Module1',[]).controller('ctrl1',CtrlFun1);
in another file
angular.module('Module2',[]).controller('ctrl2',CtrlFun2);
and in the main file, the main module, which is to be bootstraped
angular.module('MyApp',['Module1','Module2'])
This is the safest way to define services in different files. I personally advise this way of using multiple js files in single app. Because here you care not exposing a global variable or a single module, so anyone cannot inject some code using console easily.

Dynamic loading of modules and components at runtime in Angular 4

I've been looking to develop a method for loading modules and/or components into an AOT-compiled Angular 4 application and been stymied by a variety of solutions that never quite seem to get me where I want to be.
My requirements are as such:
My main application is AOT compiled, and has no knowledge of what it is loading until runtime, so I cannot specifically identify my dynamic module as an entry component at compile time (which is explicitly necessary for the 'dynamic' component loading example presented on Angular.io)
I'd ideally love to be able to pull the code from a back end database via a GET request, but I can survive it simply living in a folder alongside the compiled site.
I'm using Webpack to compile my main application, breaking it into chunks - and so a lot of the SystemJS based solutions seem like dead ends - based on my current research, I could be wrong about this.
I don't need to know or have access to any components of my main application directly - in essence, I'd be loading one angular app into another, with the dynamically loaded module only perhaps having a few tightly controlled explicit interface points with the parent application.
I've explored using tools like SystemJsNgModuleLoader - which seems to require that I have the Angular compiler present, which I'm happy to do if AOT somehow allowed me to include it even if I'm not using it elsewhere. I've also looked into directly compiling my dynamic module using ngc and loading the resulting ngfactory and compiled component/module, but I'm not clear if this is at all possible or if so - what tools Angular makes available to do so. I have also seen references to ANALYZE_FOR_ENTRY_COMPONENTS - but can't clearly dig up what the limitations of this are, as first analysis indicates its not quite what I'm looking for either.
I had assumed I might be able to define a common interface and then simply make a get request to bring my dynamic component into my application - but Angular seems painfully allergic to anything I try to do short of stepping outside of it alltogether and trying to attach non-angular code to the DOM directly.
Is what I'm trying to do even possible? Does Angular 2+ simply despise this kind of on the fly modification of its internal application architecture?
I think I found an article that describes exactly what you are trying to do. In short you need to take over the bootstrap lifecycle.
The magic is in this snippet here.
import {AComponentNgFactory, BComponentNgFactory} from './components.ngfactory.ts';
#NgModule({
imports: [BrowserModule],
declarations: [AComponent, BComponent]
})
export class AppModule {
ngDoBootstrap(app) {
fetch('url/to/fetch/component/name')
.then((name)=>{ this.bootstrapRootComponent(app, name)});
}
bootstrapRootComponent(app, name) {
const options = {
'a-comp': AComponentNgFactory,
'b-comp': BComponentNgFactory
};
https://blog.angularindepth.com/how-to-manually-bootstrap-an-angular-application-9a36ccf86429

Is it possible to create a subpage without any file?

I'm a newbie when it comes to PHP. I wrote some JS to make AJAX requests for my project and it worked well, but I don't have any idea how to convert that into PHP.
I've prepared layouts like the following:
mainLayout.php,
userLayout.php,
offerLayout.php,
In those files are some PHP and MySQL parts that build an HTML page.
In Ajax it was easy to navigate between many users using only one page and replacing some divs with data...
But a huge minus was that you couldn't have a single address reference a user profile or the offer (like mywebsite.com/user1).
Now, when I use PHP I want to achieve same layout effect.
How can I avoid creating a thousands of pages (of course even dynamically it seems to be a waste of memory IMO) like user1.php, user2.php, offer1.php, etc.
I don't know how to achieve the effect of being on a site like example.com/user277373.php without creating thousands of files but only one template.
Two solutions I see is either you use GET to parse your data:
http://example.com/?data=1736861
and than access it over the $_GET variable:
$id = $_GET["data"];
($id will be 1736861)
or you use the flight php extension, that will look something like this:
Flight::route('/id/#id', function($id){
echo "ID: $id";
});
and the URL would look like http://example.com/id/1736861. You can also use multiple variables with the flight module.
I hope this helped, Sebastian
Are you familiar with any MVC frameworks? If not, I would highly recommend getting accustomed to the MVC design paradigm. MVC = Model View Controller. From Wikipedia, a short excerpt:
A model stores data that is retrieved according to commands from the controller and displayed in the view.
A view generates new output to the user based on changes in the model.
A controller can send commands to the model to update the model's state (e.g., editing a document). It can also send commands to its
associated view to change the view's presentation of the model (e.g.,
scrolling through a document).
Two of the key components of MANY frameworks (in pretty much any language), are Routes and Templates. When utilizing a routing system, you're able to specify a template for every page loaded that matches a specific route. For instance, site.com/people/:id where ':id' can be any value in the URL, and be configured to use "person.html" for the HTML output. Note that "person.html" receives variables/data that will dynamically populate content, e.g. <h2>Hello, {{name}}</h2>
So, to clarify, site.com/people/252, site.com/people/12, site.com/people/5, site.com/people/john would all match the site.com/people/:id route path where :id is dynamic, and your system will use ONE TEMPLATE (which you specify) to display all the data. Don't forget, when that route path is met, that's only step 1. You will probably need to take that :id run some database query and pass that data into the template.
A popular micro PHP framework called Slim, might be a good starting point. Here's documentation for its way of handling Routes and Templates:
https://www.slimframework.com/docs/objects/router.html
https://www.slimframework.com/docs/features/templates.html
Slim is commonly used with Twig, a super popular PHP template engine. Here's its website/documentation: http://twig.sensiolabs.org/
And if that wasn't enough, Slim has a super handy First App Walkthrough that will show you routes, database connection, and templates: https://www.slimframework.com/docs/tutorial/first-app.html
Hope this information helps you on your journey – Best of luck!

How do I split my web application?

We create a Single Page Application. Say this is ProjectA.
We then decided, due to good fortune, to make ProjectB.
90% of ProjectA and ProjectB are the same.
This is saying to me that we need ProjectCore ProjectA and ProjectB. The latter 2 must use the first as a dependency.
What muddies the water is that, it is not just JavaScript. The Designer said "I am going to have your problem but with CSS!". So I mean, if the ProjectCore has a ConfirmationModalView, then the CSS which styles that view should travel with it.
How do you handle this? Is this what WebPack and their ilk are for? What common solutions exist for resolving this problem?
"Copy and Paste all the Code from A into B then maintain both" is getting votes but this is lame. Although I can't say I can offer a solution.
You can look into Git and version control. BUT... You could have one main JS and CSS file for the stuff that is not changing.
You can then add smaller, separate JS files, for which have specific functions, for Project A and Project B individually (Note if you include below the "main JS", all the global functions and variables will be available for this JS file to use, kind of a bonus if need be).
You can then use #import url("base.css"); at the top of your two different, smaller CSS files to "combine the main CSS with new, specific CSS for "that" page only.
you need use MVC ...
your Model are the same.. becouse it is your object manager Server Side.
your View is diferente becouse you have a diferent User Interface.
and you can dev Controller as you needed... in javascript ajax to comunicate with sever by event user... Controller php can manajer default informacion. DB Connection, Encription... ETC.
you can upload static to a server as CSS and JS and core proyect PHP to the server side...
You can add Controller 1, 2, 3 or View 1, 2, 3 depending on the project an you have a core View and core Controller.

Angular Translate - Multi Language - Static Files - Race Condition?

I'm currently using angular translate with the static files loader. I'm implementing at least 3 languages currently, however, I've noticed that typically when it's attempting to load the language file sometimes it takes longer to load the language file than it does for the view itself - which results in a partially translated UI. Most of the items on the screen will stay untranslated, but certain ones will be.
I've tried the following, with no changes:
setting forceAsyncRefresh(true) when configuring the $translateProvider.
set a $rootScope watch in the login controller (first view user will see), and on translateLoadedSuccess, call $translate.refresh().
Upgraded to the latest angular translate
99.9% of all translations are currently being done in the view, e.g.: {{ ::'My Translation Key' | translate }}
What am I missing in trying to resolve this issue? Should I be trying to manually load these language files and set them at an early load time? If so, how do I setup the use of them in the config?
I'm using Angular 1.5.0 and Angular Translate 2.11.1.
TIA!
So this actually was a race condition where the time it was taking to load up the language file initially, was sometimes (not always) longer than it would take angular-translate to static file load the language file.
As far as I could tell, there were two (2) options available - either manually load and setup the language file, or move the language file into separate smaller files themselves. However, I wanted to always be guaranteed moving forward that this wasn't going to be an issue, so I opted to manually load and setup the language file. This actually was fairly simple and required the following:
1) The language file(s) would be loaded at the top of the items in the index.html file.
2) The language file(s) would be assigned a variable in themselves - ie var enUS = { 'LOGIN': 'Login', 'USER': 'User' }
3) The language would be manually setup in the app.config:
app.config(['$translateProvider', function($translateProvider){
$translateProvider.translations('en_US', enUS); // this is the variable we assigned to the language json in step 2
$translateProvider.preferredLanguage('en_US');
$translateProvider.useSanitizeValueStrategy('sanitize');
}]);
That completely fixed all problems across all clients.

Categories

Resources