Scripts multiplies in controllers - angularjs

I'am using node.js with sails.js for backend and angular.js for frontend.
In angular i am using one main controller and some childs conrtoller.
As you know, by default in sails.js, in file layout.ejs included all java scripts and css files between tags
<!--SCRIPTS--><!--SCRIPTS END-->
and
<!--STYLES--><!--STYLES END-->
Main content are included to <%- body %> tag
When i am lifted sails, go to browser and inspect "elements" i see some problem:
main controller (let it be "myApp") in angular generating html by using layout.ejs like main body (with all css and js), and then included controllers content.
Now problem:
Problem is that another child controllers of "myApp" generating by using layout.ejs too. And thats why some scripts included multiple times.
Example: 4 child controllers = 4 included of google.maps.api. Thats bad!! code so dirty!
And now question: how i can fix this issue, and make scripts and css included just one time?

Create another layout let's call it views/blanklayout.ejs with just this content:
<%- body %>
Now, use this layout with all child controller views.
Do either
In your sails controller set layout to blanklayout: res.locals.layout = 'blanklayout';
OR you can also specify layout in routes e.g.
'GET /test': {
controller: 'TestController',
action: 'test',
locals: {
layout: 'blanklayout',
},
},
PS: You can swap layouts also, meaning have just <%- body %> in layout.ejs and another layout (e.g. mainLayout.ejs to contain present content of layout.ejs. That way you'll not have to specify to use mainLayout only for main controller view.

Related

AngularJS preload pages (off line mode)

I would like to preload templates in AngularJS (with ng-route) so that when I am on the home page, after loading all the necessaries element, I can download some sub-pages of my application in order to, if the user lost connexion, he is still able to go on that page, without an internet connexion.
I tried to make different asynchronous calls on my pages but I'm not getting anywhere.
I hope it's clear
There are two approaches for this:
The first one is to use an Ajax call and get the HTML for your Sites and load it into the template Cache by yourself:
$http.get('./template.en.html').then(function (result) {
//put template into cache
$templateCache.put('myTemplateName', result.data);
});
The second would be to use OcLazyLoad:
$ocLazyLoad.load([
'path/to/template.html'
]);
But with this approach your Template files need to look like this:
<script type="text/ng-template" id="myTemplateName">
Content of the template.
</script>
Also you could load your controller files with ocLazyLoad

AngularJs - routing between css files

​Hi all..
referring to ngRoute,
i created a single page application but would like to apply different css rules to each sub-page like background image
how can i do that?
i assigned a different controller to each sub-page
and in the link tag i used ng-href and {{name}}.css to tell the browser to grap the correct css file where is name is giving the value of the file name and attached to the scope inside the corresponding controller.
is there a need to use more than one ng-controller ?
here is the view : http://shireefkhatab.github.io/imax-design
and my code : https://github.com/shireefkhatab/imax-design​
hope to get a response
thank you all in advance.
Reefo.
You can include those styles in your template (views) or make separate route for styles, add its view in head section and then change state from your controller using $state.go('where.ever.you.want.to.go');

dynamic templates/theming system for Angular app

I am trying to create a nice dynamic theming system in my angular app.
Basically I have a Wordpress plugin which you pick via a dropdown which theme you want for my Angular app (which is on the same server in a subfolder), and I pass along the theme via a GET param, www.mywebsite.com/myapp/welcome?theme=white_theme, and the angular app in that folder currently will quickly set in the frontcontroller (think I will move this into an app.js resolve for the route so it happens before the controller, right now I just have the resolve setting a default theme):
var dynamic_theme = URI.parseQuery(query_string).theme; //url param gotten via URI js library
if(dynamic_theme) {
$rootScope.theme_name = dynamic_theme;
} else {
$rootScope.theme_name = 'default';
}
and later on in the index.html i include the dynamic theme via ng-href:
<!-- build:css(.tmp) styles/generic.css -->
<link rel="stylesheet" href="styles/generic.css">
<!-- endbuild -->
<link rel="stylesheet" ng-if="theme_name" ng-href="styles/themes/{{theme_name}}/main-theme.css">
But I also want the .html templates themselves to be able to be overwritten by our design theme for each theme.
For example, in app.js, to start off this 'questionnaire' app I have this defined:
templateUrl: 'views/main.html',
and in that file, i have a directive:
That directive uses the template 'views/question.html'
which inside of that file I decide whether to get 'views/templates/radio.tpl.html', 'views/templates/checkbox.tpl.html', 'views/templates/dropdown.tpl.html' based on the question-type passed to the directive.
like so:
<div ng-include src="'views/templates/' + currentquestion.question_type + '.tpl.html'"></div>
I guess maybe I can pass the theme into the directive (or just have access to the $rootScope) and do something like so:
<div ng-include src="'views/templates/' + dynamic_theme + '/' + currentquestion.question_type + '.tpl.html'"></div>
I was just curious if that sounds like a plan. or is there a better way to do this (or even a real theming resolver library/setup you can use for Angular that does the same things that I'm trying to achieve manually).
There seem to be a number of different ways to do this, the most promising looks to be using templateUrl as a function:
templateUrl: function(elem,attrs){
return 'views/templates/' + resolveTheme() + 'main.tpl.html';
},
You would have to write resolveTheme() yourself, possibly as a global or a service.
Alternative
Another option, if you can precompile your templates you can use the $templateCache and dynamically load the right template pack. You'd need to make sure this happened before any of the templates were requested as angular will make an HTTP request for any templates that it can't already find.
Here is one way to pre-compile your templates:
https://github.com/karlgoldstein/grunt-html2js
You could then have multiple template packs: template-theme1.js, template-theme2.js
And either build multiple versions of the app or include these templates after your application code (but before any templates get requested).

Loading partial html template into Angular app using Laravel

I'm trying to use the RouteProvider functionality in Angular. A different partial html template should be loaded depending on whether the user is editing a form, viewing a list of completed entries, etc. I've been unable to load the html templates within the same page. Instead, the user is redirected to a different page.
Here's the relevant Angular code:
.when(/new', {
controller: 'CreateCtrl'
templateUrl: 'partials/newform.html'
The Laravel Route:
Route::resource('services', 'ServicesController');
The newform.html file is located at resources/views/partials/newform.html within Laravel.
Any thoughts on how I can load these partial html templates from Laravel?
One way would be to reference the full path to the partials
.when('/new', {
controller: 'CreateCtrl'
//depending on your path adjust it
templateUrl: 'partials/newform'
since you are just using .html not tempalte.blade.php file for template you should move it to public folder.
Update:
If you really dont want to move the template out of view folder of laravel
create a route and serve your html from there
Route::group(array('prefix' => 'partials'), function(){
Route::get('/newform', function()
{
return File::get(app_path().'Views/partials/angular.html');
});
});
Note: I will suggest you not to mix Laravelc template with Angular, keep Laravel as REST API, and your Angular should separate layer.
Here are some Pros and Cons for both approach
I found another way using gulp, i leave my solution :)
In gulpfile.js inside elixir function add this line:
var elixir = require('laravel-elixir');
elixir(function(mix) {
mix.copy('resources/assets/js/angular/components/**/*.template.html', public/angular-templates');
//Find all files with suffix .template.html
});
As you notice it, i created a folder called 'angular' and then another one called 'components', there we will have our components
Angular-----------------------------
--Components------------------------
----my-component.directive.js-------
----my-component.template.html------
We have to create a global angular variable taking our browser window origin (www.myapp.com, localhost:8000, etc) by doing:
angular.module('myModule',[])
.value('pathAssets', location.origin + '/angular-templates/')
In our templateUrl we will call the template by writting:
templateUrl: pathAssets + '../angular-templates/my-template.html',
I have to say we have to concat our angular files in a file, otherwise it won't work D: if you don't know how to do it, add these lines in your gulpfile.js
mix.scripts([
'../../../bower_components/angular/angular.min.js',
'angular/app.js',
'angular/controllers/**/*.controller.js',
'angular/components/**/*.directive.js',
'angular/bootstrap.js',
], 'public/js/app.js'); //We concatenate angular files saving them in app.js
Finally execute the command 'gulp' in terminal(In our project), it should generate a new folder in public called angular-templates.
CONCLUSION
1. Move all your angular templates to public inside a specific folder by using elixir.
2. create a global variable in angular to save your origin URL and use it in your directives it automatically with this template in public.

Multiple Apps Using the Same Controller - AngularJS

I have a header that is used on every page on my website. This header containers menu items, searches, etc. I have a controller called 'HeaderController' that is used in the menu. I also have another controller that is used for the main content of the page. I have the following code that allows me to use two controllers:
angular.module('customersApp')
.controller('HeaderController', HeaderController)
I run into a problem when I am trying to use this same file on pages outside of the 'customersApp.' For example I have a 'deliveryApp' and when I try to run the top header on a page within the 'deliveryApp' I get an error saying that the 'customersApp' is not available, which I would expect.
I do not want to make a new header and file for each section of my website due to having to make changes to 5 different pages instead of 1. I am looking for a way to include all of my apps in the above code. Thanks.
Create a common module for your header controller:
angular.module("common", [])
.controller("HeaderController", HeaderController);
Then, add this module as a depdendency into other apps.
angular.module("deliveryApp", ["common"]);
and
angular.module("customersApp", ["common"]);
Make sure that the actual js file for common is also included in index.html of each of the apps.

Resources