talk about angularjs structure - how to reduce libs in index.html - angularjs

As we know, angular is a good MVC framework to build your application with single page, but I'm afraid that if taking too much work in one page, will it be a problem to load lots of javascript libs in index.html? some issue like loading slowly or even performance/network issue.
As my demo below, there's lots of js libs, and about the 'test/restful/restful.js', I want to load it when my router goes to restful.html, but I need to declare the controller in router, in index.html, otherwise the 'RestfulCtrl' cannot be recognized by angular lifecycle, so how to separate resources to reduce the work of index.html, or it is the common defect of single page MVC

The size of your controller is tiny compared to the size of all the libraries (jquery, angular, etc.) you're already loading. Having one HTTP request for each and every controller or service JS file is obviously not a good idea, but you should simply concatenate and minify those at build time, and have a single JS file to load that contains your whole application. So
<script src="app.js"></script>
<script src="FirstCtrl.js"></script>
<script src="SecondCtrl.js"></script>
<script src="FirstService.js"></script>
<script src="SecondService.js"></script>
should become
<script src="myCompleteApp.min.js"></script>
You can also choose to concatenate all the libraries and your own minified application into a single big file if you prefer, which would allow loading a single big JS file containing everything, in a single HTTP request.
Grunt and Gulp are the two main tools used to do that.

Related

loading external JS libraries / modules in AngularJS

I have a question regarding loading External JS files in Angular JS in terms of performance:
I have a small module which uses tinymce editor.
I have installed it via bower ('angular-ui-tinymce') and it works fine.
Since I'm using this library rarely, and it is being loaded on app start every time - is it better (in terms of performance) to load it in index.html async / defer like this? (to avoid being a blocking script?)
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-tinymce/0.0.19/tinymce.min.js" defer></script>
Is it possible to load external js files only when the user enters a specific module?
Thanks.
When you say "performance" in this case, you mean your bundling size I assume?
What you have to consider is if this is going to come up again down the road.
A handful of dependencies are best served when bundled together instead of several individual requests.
Even though it is not this case, if by any chance you were including dependencies that had to be configured during bootstrap they could not be asynchronously loaded.
So IMHO you want the best of both, you can always bundle and place your app on a CDN, free performance right there.

Integrating Accelerated Mobile Pages(AMP) into existing backbone application

I've a Backbone application, which initialises from index.html. I tried adding new amp html called index.amp.html and followed instructions in Create Your AMP HTML Page.
My index.html has only hook to require js to start loading backbone app. All the html is generated dynamically.
Is there a way I can include AMP practices in dynamic generated HTML? Because all I have is one index.html entire content is generated through handlebars dynamically on client side.
I didn't find any good article to make SPAs to support AMP. Are there any best practices to follow? Please help me out.
At this time, the only JavaScripts that can be triggered in an AMP document are these two scripts:
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
You can use a mustache template as part of the custom-element script as follows:
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
The templates are described here:
https://github.com/ampproject/amphtml/blob/master/spec/amp-html-templates.md
Without access to your code, can't say how easy or difficult it may be to modify your handlebar templates to fit the model above.

Sails.js and Angular.js project structure and configuration for non-SPA case

I am starting a side-project based in Sails to try it. Most of the pages are server-side rendered via EJS and don't require javascript on the front-end (my landing page doesn't, my "about" page certainly doesn't etc). However, I have a few pages that have quite a lot client-side functionality and I want to use Angular, because I am mostly familiar with that framework. The routing to these pages is again handled in the server and there's really no meaning in bundling them as a SPA.
So I am trying to wrap my mind around these concerns:
Where to place the Angular app's scripts?
Is /assets/js/dependencies still the proper place? Wouldn't placing them there make the Grunt task inject them in layout.ejs and thus in every page?
How to conditionally load the Angular base and it's components (controllers, services, etc)?
Sails uses views/layout.ejs as a base layout for loading project-wide styles, templates and scripts. Each page's controller handles injecting the body part into this layout according to the view "partial" that has been developed for that page. Is this view "partial" .ejs file the appropriate place to conditionally load the Angular app files in only the pages that require them?
How to add min/conctact/uglify of Angular' script sources in Grunt tasking?
All the Angular related files will need to be concatenated, minified/uglified for production. This will need to be a new js concatenated file to be loaded in appropriate pages apart from the "generic" js file that currently Sails tasks create and is loaded in every page. So we're essentially talking about two concatenated js files for the client side. One that is globally loaded, and the Angular one that only the pages that need it load. Which parts of the build/tasking procedure will require modifications? Some examples or resources to check would be highly useful here.
Where to place the Angular app's scripts?
Is /assets/js/dependencies still the proper place?
No, just put your angular.min.js in your dependencies folder, but not your Angular app's script. You need to put all you Angular app in the assets/js folder ( or in a sub-folder, but not in dependencies )
To be sure that each file of your app will be loaded in the right order (for example you need to load first the Js file which inject your angular app's dependencies), you can modify the tasks/pipeline.js file, and specify the order you want : You need to modify the jsFilesToInject array which contains all the Js files to load in the right order.
For example for your project :
var jsFilesToInject = [
// Load sails.io before everything else
'js/dependencies/sails.io.js',
// loading angularJS
'js/dependencies/angular.min.js',
// all the rest in dependencies
'js/dependencies/**/*.js',
// loading first AngularModule definition
'js/app/app.module.js',
// all the rest of the angular application
'js/app/**/*.js'
];
For your other question I think you need to look at the tasks/config/sails-linker.js file, that inject all the Js scripts in the <!--SCRIPTS--> tags in your HTML code.
I hope that it will help you and that I'm not too late !

How can I change angular-route.js from using Ajax to script-tag loading of partials?

I am making a mobile, AngularJS, cross-browser, offline spa with angular-route.js using no server at all. I feel changing browser defaults to allow Ajax loading of local files unacceptable for my situation. Ideally I would like an external-to-library code work-around that allows loading files via script-tag src attribute manipulation. But, I am willing to explore modifying or extending an open source library file such as angular-route.js if I knew the best version + file + line to start with.
It seems that you need to use $templateCache, you can specify the templates directly in your html using a <script> tag.
<script type="text/ng-template" id"path/to/template.html">...</script>
Of course you will probably want to have each partial in a separate file, in which case you will have to add a task that will make the partials available to $templateCache. There are plugins that will do this for you, take a look at grunt-ng-template.

AngularJS Multi-Page App Site Boilerplate Site Structure Advice

I am looking for some guidance with creating an AngularJs multi-page app served by a Laravel Backend. All web app tutorials on the net point to creating SPAs and I am just getting started with Angular - so please go easy on me.
ProductPage example - http://example.com/products/widget
<html data-ng-app='ExampleApp'>
<head>
</head>
<body data-ng-controller='ProductController'>
// ProductPage Content Served by laravel with angular tags
<script type="text/javascript" src="/js/lib/angular.min.js"></script>
<script type="text/javascript" src="/js/app.js"></script>
<script type="text/javascript" src="/js/controllers/ProductController.js"></script>
</body>
</html>
CartPage Example - http://example.com/cart
<html>
<head>
</head>
<body data-ng-controller='CartController'>
// CartPage Content Served by web-server with angular tags
<script type="text/javascript" src="/js/lib/angular.min.js"></script>
<script type="text/javascript" src="/js/app.js"></script>
<script type="text/javascript" src="/js/controllers/CartController.js"></script>
</body>
</html>
So in the above examples, I have created two pages, which are served by the web server with pretty much all static content. But the pages have been marked up with angular tags. On each static page, I have referenced a different AngularJS controller.
Is this the right way of tackling the problem or should I be allowing app.js to load up the controllers / inject the dependencies?
Also, any guidance on sharing data between controllers in this multi-page app and links to decent resources / examples would be really helpful. e.g Would I need to pass e.g. Items added to shopping cart to an api from the product page, then query this api again to retrieve the cart contents?
You should include the ngRoute module and let AngularJS load the controllers for you. Please refer to AngularJS docs to find out how to work with routings.
As for sharing data between controllers, services are what you're looking for. Creating a service is as easy as this:
app.factory("ServiceName", [function() {
return {
somevar: "foo"
};
}]);
Then, in your controllers, you inject the service like this:
app.controller("ContactCtrl", ["$scope", "ServiceName", function($scope, svc) {
$scope.somevar = svc.somevar;
}]);
The service's state is retained for as long as you don't cause a physical page reload (which is why you should use ngRoute to load your controllers).
Here you can use ngroute directive with assigning controller name dynamically.
If we use ngroute , then ngroute $scope is parent scope for both pages(html views).
Form this scope you can easily pass data from one controller to other controller.
Probably the best boilerplate/template system that I have found is Yeoman. It has a large number of great Angular templates that you can use as a starting point, and also supports automatically creating models, views, etc. from subtemplates of the main template that you choose.
Take a look at the Yeoman Angular generator, it's one of the more well-maintained angular templates that will give you a good feel for the capabilities of using a Yeoman generator.
I've worked with ngSeed for the past two years now. When it got updated to use $state it felt like a decent way to do larger apps with Angular.
Things to remember:
modularize around functionals (not layers like most tutorials do),
keep your modules small and clean,
never use $rootScope,
encapsulate shared state in a service,
don't broadcast events, but watch state,
…
Check out fountainjs. They have good boilerplates for different UI technologies.
I put a basic angular multipage boilerplate on github. It covers a working example of ngRoute and the loading of html partials and images. There's also an angular button in one of the partials that logs a message to the console. Hope it helps
https://github.com/PrimeLens/angular-multipage-boilerplate
edit: there is a controller that encompasses all pages to hold data that you might want to pass from page to page.

Resources