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.
Related
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.
I'm making a dynamic web page with angular, the content from the main page should change, but to avoid writing too much code i decided to make it generic, but to know what type of content is being requested i need to send this parameter from a link/button with a ng-click, this would'nt be a problem but when i have to change the controllers i can't read the parameter.
ng-click="name='Name change'"
Here i'm trying to change a $rootScope variable named name, i tried
ng-click="$rootScope.name='Name change'"
even with a service function, but looks like doesn't work (i don't know too much about angularjs so i tried )
ng-click="$service.cambiarTipo='Name change'"
i made a plunker http://plnkr.co/edit/1BN76SbUAHuOSHs02gpL?p=preview
If you check the console log, you will see that the variable it's undefined, obviously if i change $rootScope.name from a controller i can see it from the other controller, but that's not useful since i need that feed from the user not the controller.
How i can change a rootScope variable from html?
Here'a one using a shared service between the two controller without using $rootscope at all. http://plnkr.co/edit/maKNHgVH20GxTJeCEveh
Note that ng-click is calling the service function. I'm assuming the function is for changing the name.
ng-click="service.cambiarTipo('Name change')"
You really shouldn't be using $rootScope all that much, let alone modifying it from the template. With that said, you can assign $rootScope to a $scope variable and access from the template like normal scoped variable. plunker
Controller:
$scope.rs = $rootScope
Template:
rs.name = 'Name Change'
I would like to reiterate that this is not something you should be doing as it goes against the angular way.
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.
Currently i would like to figure out, if it is possible to execute a additional service which executes an asynchronous call and bind the response in the current scope and afterwards bootstrapping my application.
I need this behavior, because i wanted to fetch some data from a server and bind this to the scope. I tried some solutions (like the resolve method in the ui-router component) but i couldn't solve it yet.
In addition i wanted to avoid to use the $watch method to observe the variable.
Anyone have a solution for this problem?
Thanks in advance.
Short of writing your own manual bootstrapping, you can't use a service before angular has been bootstrapped. But why do you need to? You can simply fetch the data after angular has bootstrapped, e.g. like Marvin Smit mentions in the comments, fetch it in your controller:
function MyCtrl($http, $scope) {
$http.get('whatever')
.then(function success(response) {
$scope.stuff = response.data
})
}
Angular's directives and interpolation are written with this in mind, and would not error if there's no $scope.stuff defined when the controller is executed.
Or you could use ngRoute/ui-router and the resolve parameter for a route(see https://docs.angularjs.org/api/ngRoute/provider/$routeProvider)
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