Pass a variable from controllers - angularjs

I am programing in Angularjs, and have have a page that is divided into 3 teplates which one has an html file and js file.
The js file of which template is characterized for having the controller of the html of that template.
At the end i want to pass a variable from a certain controller to another how can i do that once they are in different controllers. Thanks
Mr.Avraam Mavridis, here is some code:
Basically down here is the controller that i want to get the value of the parameter (clientPosition) to pass it to another controller:
crm.controller("clientsModule", ["$scope", "$http", function ($scope, $http {
$scope.changeTemplate = function (index, clientPosition) {
$scope.panelTemplate = index;
$scope.clientPosition = clientPosition;
};
}]);

There are various ways you can achieve this. The easiest way to do this is using a broadcast and watch. You basically set the value in the controller you want to and create a broadcast event for it. In the controller that you would like to access the value, you put a watch and listen to any updates for the value.
The above way is also the dirtiest way to achieve what you want
A more elegant solution would involve create a model binding on the view and accessing those properties via logical progression on the controller you want to access that value in. You essentially create an angular service for your models and then access those services in the controllers.

Related

AngularJS - Sharing data from a parent route controller to all child directives on the page

I have a page that has multiple components and I've created each component as a directive. When the page is first loaded, that's when I grab all the data that should be available on the page. So all of the data exists on the controller for that route, which we'll just call pageCtrl. And then what I've been doing is binding any required data to each directive through the attributes, which of course ends up creating an isolate scope for each of them.
I know there are a few ways to share data, so given this situation, is there a recommended way of doing it? Or has anyone had better success doing it one particular way? While it's working perfectly fine the way I'm doing it, I've run into a few caveats. If I need just even one bit of information from the pageCtrl, I need to add another attribute to the directive. So it ends up creating more code on the directive element itself.
I was thinking about just creating a service that would store all the data, which the pageCtrl could initialize, instead of setting it on itself. Any feedback would be appreciated.
good question :)
First solution is to create in parent controller object and pass this object (via ng-model) to all directives. This object will be passed by reference (not by value) so controller and all directives will have access to the same object.
```
// in controller
$scope.shared_data = {someItems: []};
// in html
<my-directive ng-model=shared_data></my-directive>
Second solution is to create some simple service to store all of those data.
// in this solution you have to inject additional service to directive controller
(extended idea of point 2) creating service/factory that will be responsible by collecting and returning data. This service could be injected into directive and use the same methods to collect data. To avoid making multiple calls to API (REST) it could have some cache for each sensitive method.
Communication via events.... (probably the worsts solution for your example)
The first two ideas are probably the best, I do not know full specification of your product so final solution picking belongs to You:).
My advice is to try/play with all of those methods to really understand what is going on and how and when to use each of them :)
You can directly call your parent controller from child directive controller by using $parent.
App.controller('aCtrl', ['$scope', function ($scope) {
$scope.refresh=function(){
.......... //Updated Data get from DB
};
...........
}]);
App.directive('bDirective',function(){
restrict: 'EC',
replace: true,
scope: {},
controller: function($scope) {
$scope.$parent.refresh();
}
...
});
HTML:
<div ng-controller="aCtrl">
<div class="bDirective"></div> //directive
</div>

Same Angular controller for different view

I have a requirement to list, edit and delete an entity. I have different views for each of this operations. I want to know if it is a good practice to use the same Angular just controller for these operations that works with each of the operation or should there be a separate controller for each?
Also if using same controller for these operations, is it possible to call different function when different views are loaded? So when user goes to the list view, a list method is called on page load and when he goes to the edit view, an edit method of the controller is called on edit view's load. I manage to achieve this by calling the methods using ngInit but apparently that is not recommended in v1.2 and should only be used with ngRepeat.
My question is similar to this one. Angular - Using one controller for many coherent views across multiple HTTP requests
However I also want to know if there is a way to call different initialisation methods of the same controller depending on the view the controller is used by.
A better approach could be to write a utility service which can be used across the controller. Use this service in your different controllers.
Your service will look something like this:
(function() {
'use strict';
// this function is strict...
angular
.module('myapp.services', [])
.service('Utility', function() {
var Utility = {};
Utility.edit = function(id, dataset) {
//perform edit related task here
};
Utility.delete = function(id, dataset) {
//perform edit related task here
};
return Utility;
})
}());
I have got my answer here: Using same controller for all CRUD operations (Rails-alike)
Apparently it is a good practice to use a different controller for each view, and it shouldn't work as a service. This is quite different for someone coming from MVC/WebAPI into angular.

sharing data between two controllers which keeps on updating

I want to share data between two controllers using some factory method. The controller Ctrl1 belongs to the first DIV tag from which HTTP request is sent and data from server is received in streaming fashion. And in other DIV tag, I want to display that result as a list (ng-repeat) which keeps on updating as the HTTP result in first DIV gets updated (also, second DIV tag starts displaying results as soon as first DIV tag gets first response, and first DIV disappears). I know how to pass data between controllers one time (e.g. ng-click="pass()"), but not sure how to achieve this. I am looking for an answer which does not uses $rootScope.
You should create a service to contain the data, then inject the service in to each controller.
For example, lets define a 'myService' service with one property 'foo' equalling a string 'bar':
angular.module('myModule').service('myService', function() {
this.foo = 'bar';
});
We can now use this in a controller as so:
angular.module('myModule').controller('MyCtrl', function($scope, myService) {
$scope.myService = myService;
});
This is now accessible in the template as {{myService.foo}} or ng-model="myService.foo" as usual.
You can then use it in a second controller in a similar way, when you update the property 'foo' in either controller the changes will persist between controllers. This is because services in angular are singletons. What you're doing by defining a service like this is creating a singleton 'myService' which can be injected wherever you want and will always be instantiated only once.
If you need to watch for changes within the controller code, you can use $scope.$watch() as usual on myService.foo.

Controller factory in angular

In AngularJS, I have two lengthy controllers, which are identical - except for one variable definition at the top (which is used in multiple places throughout the controller to decide what to process).
How can I consolidate these two controllers into only one controller?
Is there something like a controller factory that can take in an argument (my variable)?
Can you pass a variable to a controller, when specifying it in the router? Can you pass a variable when manually calling a controller via ng-controller in the html?
Something like this:
ControllerA
{
mode = 'A';
MakeControllerRealAndUseItInsteadOfCurrentController(mode);
}
ControllerB
{
mode = 'B';
MakeControllerRealAndUseItInsteadOfCurrentController(mode);
}
ControllerReal( mode )
{
mode = mode;
// actual controller content
}
Controller in Angular are tightly bound to the view they interact with and in fact the view has declaration of ng-controller based on which controller is instantiated. Controllers are not utility functions that can be shared across the app\views. Since the controller are doing similar function, it maybe the case that the views are pretty similar.
Some of the ways that you can reuse the controller code would be
Refactor any code that does not directly affect the view into service and call the service from your controllers.
If the view are similar may be look at reusable directives, with their own controllers, for create a specific part of your view, which can be used across views.
For the point above you can also create partial templates which can have their own controller, and reuse them using ng-include.

Angularjs: two way data bindings and controller reload

If use routing and controllers, then model not save his states between controller reload. Angular create controller instance and new scope on every route load.
For example, i type something in input that have ng-model="something", go to another route, then back to first route. All my typed text is lost.
I need simple two way data binding between routes changing. As simple as possible, like ko.observable in knockoutjs. Or implicitly like in angular within one controller. Maybe with singleton $scope for controller?
I found the way, when i create service for saving data between route changing, and inject it into controller. In controller's constructor i create model with value from service, and $scope.watch this model for changes, and on change i set model's value to service.
Is there any simpler way?
You are right - services is right way for doing this. You can use it like so:
app.js
app.factory('paginationService', function() {
return {
cur: 1,
total: 9,
pageSize: 8
};
});
app.controller('Page1Ctrl', function($scope, paginationService) {
$scope.pagination = paginationService;
});
Page1.html
<div ng-controller="Page1Ctrl">
<h2>Page1</h2>
<p>curPage: <input type="number" ng-model="pagination.cur" /></p>
</div>
See full example.
You could inject $rootScope into your controller and use it to store globally accessible variables, though you would still have the same issue watching for changes. You could create a directive which would inject your service into the current scope, and have it bind watch handlers in the scope as well.

Resources