How to combine two controllers in Angular.js? - javascript

I'm new to Angular, and I've got two seperate controllers that work fine separately, but when I try to combine them in the same page, on of them gets broken. You can check them out here:
http://plnkr.co/edit/RUKCNUsiLLHja5BCsOXi?p=preview
http://plnkr.co/edit/UkGEaquNkXGfUgbuYBki?p=preview
I've tried to combine both controllers like this:
var app = angular.module('App', ['audioPlayer'], [ngSocial]);
But that breaks it as well. Do you think it has anything to do with the Ionic framework I'm using?
Thanks for any help!
EDIT: Here's the working demo http://plnkr.co/edit/0eQZ0O?p=preview

Could you show the third example where it actually breaks. It looks like you should have:
var app = angular.module('App', ['audioPlayer', 'ngSocial']);
If you're actually talking about combining modules. The first parameter to angular.module is the string name of the module you're defining, the second parameter is the array of dependencies.

Related

Implement a logical part as Generic one in AngularsJs

I have recently started working on ANGULARJS in which I was encountered a case where I need some guidance to go through. Am implementing a message section in my application(ASP NET MVC - ANGULARJS).Currently I have implemented the message section for a specific module under a particular ng-app and under particular ng-controller. Now I need the same functionality to be used inside another module. It's like duplicating the same code again that ng-app under that ng-controller which was not a good approach. I just wanted like and plug and play kind of approach for my ANGULARJS code.
I have used 2 service,1 directive under that particular ng-app and some functions inside a particular controller. All I want is to make these one a common code and to be used inside under any ng-app and ng-controller.
Is this possible? If so how can I achieve.
Let me know if the query was unclear
You said you used 2 service, 1 directive, and controller etc for your messaging feature. If you want to re-use it across various applications, you need to bundle all of this as a module. for example:
angular.module('customMessaging', [])
.controller('messagingCtrl', function(messenger, messageManager) {
....
})
.directive('messagingDir', function() {
return {
controller: 'messagingCtrl'
...
}
})
.service('messenger', function() {
...
})
.service('messageManager', function() {
...
})
Now you can specify this as a dependency of any of your angular applications as shown below to access the directive, services and controller anywhere in the app:
angular.module('myfirstApp', ['customMessaging']);
angular.module('mySecondApp', ['customMessaging']);
Thanks for the suggestions. I have moved the message related functions such as services, directive and controller related functions into separate JavaScript file . And invoked this JavaScript file where I need message related functionalities.
Let us say that JS as Message.JS . In Message.JS I have used the app variable(Instantiated app from the JS Specific to the page globally).
JS specific to that page
var app = angular.module('appname',[]);
app.controller(...)
Message.JS
I have used the same app in my message.JS since message controller falls under that app.
app.service(...)
app.controller('messagecontroller',[]...)
When ever I need to invoke a function inside MessageController I will use Broadcast in angular to achieve this.For more info http://www.dotnet-tricks.com/Tutorial/angularjs/HM0L291214-Understanding-$emit,-$broadcast-and-$on-in-AngularJS.html
Regards,
Selvam.M

How to avoid angular loading multiple times when adding directive?

In my app.js file I have the app being created like this:
angular
.module('AngularRails',[
'ngRoute',
'templates',
'firebase',
'mySharedElements',])
i'm attempting to load a directive in one of my views like this:
angular.module("mySharedElements", []).directive('userItem', [function()
However, this doesn't work? I receive an error in Developer Tools stating that Angular attempted to load multiple times and thus the tab locks up. I tried solving that but adding 'mySharedElements' as you can see from the code but that didn't work. From various sites I've read, I'm doing it the right way so I'm confused what I'm doing wrong because obviously I am.
Thank you for your help, I appreciate it. :)
UPDATE:
I double checked and i'm not using ng-app more than once. The error only occurs when I attempt to go to the page where the directive is being used.
I update the app.js file and the directive to this to see if that fixed it:
app.js:
angular
.module('AngularRails',[
'ngRoute',
'templates',
'firebase',])
.config(function ($routeProvider, $locationProvider) {
// etc.
directive:
angular.module("AngularRails").directive('userItem', [function() {
// etc.
And that fixed it. It looks like I was suffering from a combination of this and I had the templateURL wrong in the directive and it was screwing stuff up. THANKS!
angular.module("mySharedElements", []) will create a new app because you are passing second argument to module with empty dependencies.
If you have already created the app somewhere else in your code then you just need a reference to it. Change it to angular.module("mySharedElements").directive then it should be fine.
However looking at the error description mentioned in the question Angular attempted to load multiple times, it looks like you have multiple references to angular js on your page. Try to check for that and remove multiple references.

Code seperation in AngularJS

I'm quite new to AngularJS so please bear that in mind when reading this question...
I have some functions that I would like to make globally available to different modules within my website, plan is to have pages performing their own functions in a single page app style (so a user list / create / modify would be one page, and a product list / create / modify would be another). I would like to have some shared logic, say utility functions, and also user authorisation that can be shared between the different page modules.
This leads to my question.
Assuming I have all the account functions encapsulated within a service (app.factory('account, etc etc...') for example) and separated into it's own JS file, is it better to place it within it's own module and using dependency injection like so:
var accountMod = angular.module('accountModule', ['dependencies']);
accountMod.factory('account', ['dependencies', function (...) { }]);
Or just assume the name of the app variable will always be app and express it like so:
app.factory('account', ['dependencies', function (...) { }]);
Functionally both of these work, but I am trying to use best practices. The second option seems limited, I have never been keen on assuming variable are the same name throughout, for me the dependency injection method seems better but I have seen many examples of both styles out there!
Any help is much appreciated!
Really nice question. There are subtle things in this.
I think it would helpful to use following code, which is using module.
var accountMod = angular.module('accountModule', ['dependencies']);
accountMod.factory('account', ['dependencies', function (...) { }]);
However with help of angular provider and adding module level config we can mock object or service. Eventually this will increase the test ability of code.
If there are multiple services under accounting, then I would prefer to group them inside module.
These are my aspect of to look at it. Please add more if you found.
Thanks.
Just my 2 cents on your code examples.
The following approach is not recommended:
var accountMod = angular.module('accountModule', ['dependencies']);
accountMod.factory('account', ['dependencies', function (...) { }]);
A best practice is to only have 1 component per file, therefore no need to define a variable. Take a look at this: https://github.com/johnpapa/angular-styleguide#definitions-aka-setters
If you are just starting out with Angular, I recommend that you go through the rest of John Papa's Style Guide.
I love the structure that angular fullstack generator for yeoman has.
https://github.com/DaftMonk/generator-angular-fullstack
You can see how each module and component is separated and inside, de factory, services, directives, etc. and their associate test are split in one file per functionality.
This probably is overkilling for your propose, you can take only the angular idea.

AngularJS .ng-enter animation doesn't work on first run

I'm have a strange problem in my AngularJS app; Animation in my tab-slides switching with ng-include, doesn't work for first time, but works good in second or third time.
Here is my test code on plunker: http://embed.plnkr.co/a2x4vkTVgEUEt9mxWaVy/preview
Looks like ng-enter animation class, setting before, template uploads. Please, help.
It looks like the animation isn't working as your templates are getting loaded out of turn. I recommend either using directives for implementing tabs, or ngRoute.
I have made an example with ngRoute here:
http://embed.plnkr.co/RFw3CZwQmPz9doqe7o1u/preview
I'm not entirely sure what your app is supposed to do, so I may have broken your initial setup.
But I see you're using a lot of rootScope. I recommend using a service for storing shared data between the controllers. Like this (using example from here: Passing data between controllers in Angular JS?)
app.service('productService', function() {
var productList = [];
addProduct = function(newObj) {
productList.push(newObj);
};
getProducts = function(){
return productList;
};
});
Update: It is possible to use dynamic templateUrls in the $routeProvider, like this. This is also possible with the controller. That way you don't have to specify a seperate route for every one of your steps.
Ok, i'm found solution for my own question, if you have same problem, you must use a $templateCache service, and here is code on plunker:
http://embed.plnkr.co/mnB6VwXqHSt6L3IEUvCI/preview

AngularJS loading controllers from folder

im new in AngularJS, and have question how i can load controller and other js from structured folders?
For example i have structure:
app/
-common
-users
--userController.js
--userService.js
-orders
-app.js
How i should load controller and service from folder user?
And one more small question: what means squre bracerts?
app.config(['someThing'], function($routeProvider)
You can put the your code where you wants to. If you put them into angular modules, angular will find it. So if you have a service in /app/common/services/foo.js like:
angular.module('app').service('foo', function() { ... });
You can do this in the userController:
angular.module('app').controller('UserController', function($scope, foo) { ... });
Here you see how I injected foo in our controller. Angular Dependency Injection system is smart enough to find your code no matter where you put them.
You can also create different modules than app, you can have:
angular.module('other').service('bar', function() { ... });
And where you define the app module, something like this:
angular.module('app', []);
You just need to add the new module there as a dependency, that is what the [] are for:
angular.module('app', ['other']);
Now you can use the service bar in your controller too :)
On the other hand, the syntax you're talking about is the array notation, something like this:
angular.module('app').controller('FooCtrl', ['$scope', 'foo', function($scope, foo) { ... }]);
This is needed if you mangle your code when you minify it because in the minified code, you could get something like this:
angular.module('app').controller('FooCtrl', ['$scope', 'foo', function(f, g) { ... }]);
As you see, the function parameters are now f and g and Angular doesn't know what to inject based on those names, so it looks on the strings we provided, so it will know that f is $scope and g is foo.
There is no need to use this annotation directly, there are several tools that will do that for you like ngmin.
Cheers.
EDIT: You would need to add every javascript file into a <script> or the won't get loaded and Angular wouldn't find it.
Adding the files one by one is a pain, because you can have 5 or you can have 200.
It is better to concat them and for that I recommend: grunt-concat-sourcemap because it will generate a sourcemap so you will have 1 file with the entire app but in the dev tools you will see them in separate files.
I recommend you to check linemanjs which is a good tool to develop javascript apps and it concat the files for you, source maps, minify, the array notation stuff also...
You will have to link all files in your main HTML page and make sure they are loaded. As pointed out by Dwight above.
An alternative approach would be to use something like Grunt.js to "build" the app. This would include combining all the controller.js files into one – which you then load into your HTML page. This way all the files will be separate for development but will get concocted for deployment.

Categories

Resources