Suppose my angular js app(myApp) has a controller and directive, How would I be declaring both?
angular.module("myApp",[])
.controller("myController"......
angular.module("myApp")
.directive("myDirective".......
OR
angular.module("myApp",[])
.directive("myDirective".......
angular.module("myApp")
.controller("myController"......
If you see the above code, I am defining my angular app on a controller, and then just retrieving it for the directive. In the second case, I am defining my app for a directive, and retrieving it for a controller.
Which is the right way? How to decide on what is the correct way?
Both are correct. It doesn't affect the way the application is bootstrapped.
You only need to understand what angular.module() does.
angular.module("myApp",[]) creates a new AngularJS module named "myApp" with the dependencies passed as the second parameter.
angular.module("myApp") is a getter. It returns the module if it has been created before.
Both return the same object. So then, you can add your directives and controllers in the order you want.
Once everything is loaded, AngularJS starts the bootstrapping process. See the AngularJS documentation.
Related
var myapp=angular.module('myAppln',[]);
I am new to angularjs. Why should we use [] in angular.module()? Could anybody please explain.
This is used for injecting dependency. Dependency Injection or DI is a software design pattern in which components are given their dependency instead of hard coding them within the component. This is also helpful in making dependency configurable and make components resuable & maintainable.
Components such as services & directives are defined using injectable factory
For example when define a service in angularjs we do like this way
var abc = angular.module('ngAppName',[]);
abc.factory('serviceName',['$http',function($http){
// Rest of code goes here
}])
angular.module('ngAppName',[])
It is more or less entry point for angular application & here we do not have any dependency so this is an empty array.
But take a look when we are defining our custom service.Here this service has dependency on $http which is predefined service offered by angular for ajax call.Our custom service(serviceName) has dependency on this $http, which we are injecting here
Another example with angular route
abc.config(['$routeProvider',function($routeProvider){
// Rest of code goes her
}])
The $routeProvider is what creates the $route service and it is provided by angularjs. While creating route we have to depend on $routeProvider. So we have injected it our code.
Hope this will be helpful for you.
if you go further in Angular.js then you will read that you can pass injectors and other stuff to module. So here api return in a manner that it receaves array of options. when you wont have any you just pass it blank []
Actually [] is an array with the dependencies that are required by the module.
I have just started working in angular.js and I have created separate angular applications (using ng-app) for separate modules of my application for modularity sake so that change in one module does not bring down the whole application.
Now, i am running into a issue of redirecting from a search form common across all modules to a particular page (in a specific module). I thought of saving the value in $rootScope, but while debugging, I found that $rootScope is per ng-app, so, it will not work.
Am I wrong in designing the application into separate angular applications and should I move everything back into one ng-app? or is my application structure correct and I should look for another way of passing value?
EDIT: - I think I did not provide enough detail earlier.
My application is structured as follows:
module1
- controller\controller-module1.js
- service\service-module1.js
- css\module1.css
- view\ <multiple html files>
module2
- same structure
I was actually using the service-module to make REST calls to the server till now, rather than sharing data.
All the modules are defined with their separate dependencies in app.js:
angular.module('Module1App', ['Module1App.controller','Module1App.service']);
angular.module('Module2App', ['Module2App.controller','Module2App.service']);
controllers and service of each module are defined in their respective controllers-module.js and service-module.js, which reside in different directories as per the structure above.
So, to include the controller and service of a particular module(of, say, module1), I declare the following in a view of that module
<script src="/APP_GUI/modules/common/service/services-common.js"></script>
<script src="/APP_GUI/modules/reports/service/services-module1.js"></script>
<script src="/APP_GUI/modules/common/controller/controllers-common.js"></script>
<script src="/APP_GUI/modules/reports/controller/controllers-module1.js"></script>
So, if I have to move all ng-controllers (defined in separate directories as per the module structure above) into one ng-app (app.js above), I will basically end up including all the controller.js and service.js in all the html views, which will basically mean that if there is an error in any one of the js files, my entire application will be down (i have tried it out).
So, unless I have misunderstood something, I cannot move all ng-controllers under a single app.js.
I am going to try out using shared services to share data.
Please let me know in case anybody has something to say on my conclusion.
I don't think using many ng-app is a good approach. I suggest you using many ng-controller in separate file instead.
You can keep variables inside objects instead of using $scope, which most tutorials you'll find online don't explain.
For example:
/// Define the app
app = angular.module('MyApp',[]);
///Add a cotroller
app.controller('MyFirstController', ['$scope', function($scope){
/// using 'this' you can write local properties
this.firstLocalProperty = 'first Value is acessible only in MyFirstController';
this.secondLocalProperty = 'second Value is acessible only in MyFirstController';
$scope.firstSharedAppProperty = 'This is Shared between all controllers in app';
}]);
app.controller('MySecondController', ['$scope', function($scope){
/// here you can use shared and local properties, you may access shared things in $scope
this.fistProperty = $scope.firstSharedAppProperty;
}]);
You'll see that
> MySecondController.firstProperty
'This is Shared between all controllers in app'
but
> MyFirstController.firstProperty
'first Value is acessible only in MyFirstController'
MyFirstController.firstProperty keeps it's original value because it's not shared.
Basically, you should use different controllers for different templates instead of using different modules. Using controllers, you may share items between them in the $scope variable. Or you can keep variables private using this reference inside objects.
Take a look in this article and you may understand better this way.
You should be using multiple controllers and then using a common service shared between your services. Services in angular are singletons, so they can be shared over and over and over again, and will be common across the board, including between applications if you inject the shared functionality as another application.
var app = angular.module('firstApp');
app.service('myService', function(){
var self = this;
return{
getValue: function(){return self.value},
setValue: function(value){self.value=value}
}
});
app.controller('firstController', ['myService', function(myService){.....}]);
app.controller('secondController', ['myService', function(myService){....});
var secondApp = angular.module('otherApp',['firstApp']);
secondApp.controller('otherController', ['myService', function(myService){.....}]);
more importantly, if its doing anything more than just storing values you can inject functionality for better testing!
Angular extends the 'this' variable of a service function with the scope (viewmodel) of the controller that is using it. Maybe I'm misunderstanding a design-intention here but it makes no sense to me.
Here's an example on codepen to illustrate the problem. When the class function (TestService) gets initiated, this is empty, but after a brief timeout, it suddenly contains the $scope from the controller.
How can I avoid the injection of $scope into my Service?
Optionally, It'd be great if you could explain the reasoning behind this behaviour as well.
The problem is with your dependency injection. You have used
angular.module('app', ['service']).controller('ctrl', ['testService', function($scope, testService){
Whereas it should be
angular.module('app', ['service']).controller('ctrl', ['$scope','testService', function($scope, testService){
So what you thought was scope is actually the service itself testService. Scopes can never be injected into service, even if you want to. You can only inject $rootSscope into a service.
Another advice that i would want to share, would be to not do DOM referencing in controller, service better to go with directives.
I'm building an application based on AngularJs and GMaps API v3. The issue I've came up with is that I need a way to call methods of the directive's controller from another directives (that's easy with require) and from the same directive.
Let's put it in an example:
I've got a directive that renders the map using GMaps JS lib. and also render some markers and also I've got another directive that handles navigation (i.e. Changing routes). When I go from route A to route B I need to erase the markers and leave the map blank.
So which is the best way to achive this? Should I build three directives? One with all the render methods and destroy markers methods and then call them from the other directives? Or is there a way to inject the directive's controller into the same directive?
So I've googled a bit an I've found this!
https://github.com/bennadel/AngularJS-Directive-Controllers/blob/master/app/directives/master.js#L11
Just like you said #musically_ut the controller is executed before the link function so it's could be injected into the link func. and make it's method available.
The controller for a directive executes before the link function and all $scope declarations made in the controller are available on the scope of the same directive.
Hence, the controller is injected into the directive itself.
Demo: http://plnkr.co/edit/HnwJ0w0VTLbNOC87k74n?p=preview
I am trying to broadcast a message from legacy javascript function into Angular controller(s) via a Angular service. Broadcasting works fine when called within Angular, but not outside.
See http://jsfiddle.net/yh3Ds/24/
It seems that angular.injector() is creating new module instance and
it is independent from the module instance bound with the html via ng-app attribute.
So solution is to use manual bootstrap and obtain the injector there.
Use this injector you can access the service instance and $rootScope which
is actually controlling the view.
Here is the updated fiddle; http://jsfiddle.net/d8vX3/1/