Multiple Apps Using the Same Controller - AngularJS - 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.

Related

Multilingual with multiple app and 1 translationService

I'm currently make a html page by using angularjs.
I have 1 html page, with 1 sidebar, 1 navigation bar and 1 content area.
Like this : AdminLTE
I've follow this instruction : this
And successfully, my app works ok.
But I don't know how to apply multilingual function to my every app.
For example : Navigationbar is 1 app, sidebar is 1 app and main content is 1 app.
How can I apply 1 translationService to 'em without downloading json again and again ?
Can anyone help me please ? Thank you.
I still think it would be better to have one application for the whole page, but have separate controllers for the nav, sidebar, and main content. That way they all work separately, but you don't have the awkwardness of dealing with separate apps. The only reason I can think of to have separate apps is if you want to make sure that services are NEVER shared between the different parts. However, in your case, it looks like you WANT to share the translate service, so I think it makes sense to use one app.
If you really want to have multiple apps, it is still possible. You can load the translations asynchronously, then when this is done, you call angular.module() for each app and inject the translations as a constant. Then, when you configure the translate provider, you can inject your translation constant just like you would inject any service.
I have done this in an application before, but I don't have access to the code right now. I did it for a single application, but you can easily extend it to multiple applications. I believe it looked similar to this:
var $http = angular.injector().get('$http');
var $q = angular.injector().get('$q');
var promises = [
$http.get('path/to/translations/en.json'),
$http.get('path/to/translations/fr.json'),
];
$q.all(promises)
.then(function(translations) {
angular.module('app', [])
.constant('translations_en', translations[0])
.constant('translations_fr', translations[1])
.config(['$translateProvider', 'translations_en', 'translations_fr',
function($translateProvider, translations_en, translations_fr) {
$translateProvider.translations('en', translations_en);
$translateProvider.translations('fr', translations_fr);
}]);
angular.bootstrap(element, ['app']);
});
For multiple apps, you would need to run the angular.module block once for each app.
Alternatively, you could define separate modules for each part, then define a parent module that depends on the other mini-modules, i.e.
angular.module('navigation', []);
angular.module('sidebar', []);
angular.module('mainPage', []);
angular.module('app', ['navigation', 'sidebar', 'mainPage']);
angular.bootstrap(element, ['app']);
I believe that all modules would share the same translate service in this case.

How to deal with templates of completely different areas (but same website) with AngularJS

I have a webapp with a main index.html that shows each page through an ng-view and a routeProvider.
Now I'm adding an entry page for users who are still not logged in. This page could also have his own ng-view to slide different sections for non logged users (welcome, what is, sign in, sign up ecc...) and his own head with css scripts ecc...
I'd rather that both the webapp index and the entry page index address to www.example.com (so nothing like www.example.com/welcome ).
I thought about a structure similar to this:
webapp/
main/
page1/
page2/
welcome/
section1/
section2/
index.html
welcome.js (angular module for the entry page)
.htaccess
index.html
webapp.js (angular module containing the routeProvider for the webapp)
Currently I have that .htaccess that rewrites all the fake queries to index.html so that everything is handled here.
So in particular:
1) How can I say to the routerProvider of webapp.js to go to /welcome/index.html when the user is not logged in, if I already use this condition for the webapp main page? (Should I use the run method? a brief example will be helpful)
.config(['$routeProvider', function($routeProvider){
$routeProvider
.when(...)
.when('/', {
templateUrl : 'main/webapp-main.html'
})
.when(...)
2) How do I prevent that everything in welcome/index.html will be loaded within the index.html ng-view? (maybe using ng-if to hide ng-view? or there is some way to control this behavour with the routerProvider?)
3) There is a better and simpler way to achieve all of this?
Thanks.
Update:
Ok I think there was an underlying problem in my question... I can't use a complete different page since everything is loaded in and switching to another page will cause the reload of the app loosing all the data.
So I suppose I should use the same main template for the entire website.
Then I add: there is a way in angularjs to load different style sheets dynamically?
this questions is old but i think is valid and can clarify someone a few thinks.
First of all you are suppose to use a single page for AngularJS apps, otherwise you will have to do something like a redirect link, and in your other-index.html load an entirely different Angular Application also loading every script needed in the first one.
1) Use ui-router is easy to work, and very robust, the only thing you need to have is a container for your ui-view then the ui-router will fill the container with the corresponding html
2) To prevent navigation you should do something like this:
angular.module('myApp', [])
.run(function($rootScope, mySessionService){
$rootScope.$on('$stateChangeStart',
function(event, next, nextParams, prev, prevParams) {
// The info of your currentUser could be obtain from a service
// or localStorage or cookies anyway you are already doing it
var authorized= checkAuthorization(next.authorazedRoles,
mySessionService.getCurrentRol());
if(!authorized) {
$rootScope.$state.go('defaultState');
// Or $rootScope.$emit('NOT_AUTHENTICATED');
// and some service will have to implement a listener for this emit
// $rootScope.$on('NOT_AUTHENTICATED', func..redirect to X State)
}
});
});

AngularJS register controller once

That's what I'm doing. There is application with pages and different controls that may be put on pages by site admin/editor. All pages share one ng-app defined on master page. All controls are supplied with .js files with angular controllers. Let's suppose that I have an image gallery block:
<div ng-controller='imageGalleryCtrl'>
do something amazing here
</div>
<script src='imageGallery.js'></script>
Inside script there is a simple controller registration like:
angular.module('myApp').controller('imageGalleryCtrl', ... );
So. If I have 10 image galleries, I'll execute controller registration 10 times. It looks like this will work, but hell - I don't want it to be so =)
For now I just have all controls' scripts registration on a master page, but I don't like it as well, because if there is no image gallery on a page, I don't want it's script be downloaded during page load.
The question is - is there any proper way to understand if controller have been registered in a module already and thus prevent it from re-registering?
---------------
Well, though I've found no perfect solution, I must admit that the whole idea isn't very good and I won't think about it before my site will grow too big to assemble whole angular app on master page.
You should declare your controller but once. Instead of having one controller per gallery, have your single controller handle all image galleries. The controller should make a request to the REST backend to fetch the images of the desired gallery.
I see that instead of ng-view, you're using the ng-controller directive, indicating that probably you're not using Angular's routing. Try switching to using routes.
Have a look at Angular.js routing tutorial. It shows you how to use the ngRoute module. Then, in the next chapter, the use of $routeParams is described. Via the $routeParams service, you can easily say which gallery should be displayed by providing its ID in the URL; only one controller will be necessary for all your galleries.
If you really must check whether a given controller has been declared, you can iterate through the already declared controllers (and services... and pretty much everything else) by checking the array angular.module("myApp")._invokeQueue. The code would probably look something like this (not tested!):
var isRegistered = function(controllerName)
{
var i, j, queue = angular.module("myApp")._invokeQueue;
for (i = 0, j = queue.length; i < j; ++i) {
if (
queue[i][0] === "$controllerProvider"
&& queue[i][1] === "register"
&& queue[i][2][0] === controllerName
) {
return true;
}
}
return false;
};
Bear in mind however that while this may (or may not) work, it's far from being the correct thing to do. It's touching Angular's internal data that's not meant to be used in your code.

Do we need multiple controllers to implement routes in angularjs?

There is chance that I might not be able to explain my problem properly. Let me try.
I am developing a single page application using angular. This app basically displays the episodes of an online novel series. There is a navigation bar, which has query menus (Like, latest episode, episode of a particular date, episodes with a particular tag, etc). For each of these queries, i want a separate url.
/latest - should display the latest episode
/tag/:tagname - should return all episodes with that tag.
For all these queries, the resultant view is the same (list of episodes). So I will be using the same partial for all routes.
My question is, Should I actually create a new controller for each query? like, LatestEpisodeController, TagController?
Is there anyway I can use the url to determine what the user wants and run that query from within the same controller?
Ofcourse you can use same controller in routing definition, the question is what is the purpose of that? It will be worse to debug it later, if you have a shared functionality it's better to turn it into a factory or service and then use in controllers.
But the answer is YES, you can use same controllers and implement different behaviour basing on i.e. $location.path()
yes you can use single controller for multiple routing..
you can create different functions in controller and in each function do the according job.
In my case I have created different html page for different url and registered same controller for the html pages and in the html page I have called controller method using ng-init in div portion.
You can use same controller and same views as you wish...
$location can help you to get current path or full url if you want and you can call your service depends on your path...
here I write a little example for you to get the idea
PLUNKER

How to redirect in AngularJS without rendering template

I'm trying to redirect to an external page from my AngularJS file if the user enter a special url, for instance /test. I have gotten this to work in multiple different ways but all the different ways show a "flash" of the design from index.html. I would like it to go direct without rendering any html at all!
Here is a fiddle of one of the examples, but it is not the best place to test since I cant redirect from jsiffle.net :-)
$routeProvider.when("/test", {
resolve: {
controller: "Redirect"
}
});
Also had one example where I just used a controller and a empty template in the routing, but it gave me the same result.
Any ideas?
If you know the URL(routing) then use,
$location.path('the_URL');

Resources