Combining functions from two separate controllers into one ng-click - angularjs

I am new to angularJS and nodeJS and am working on a project. As it stands there exists two different controllers let's say "controllerA" and "controllerB" that have "functionA" and "functionB" being triggered by ng-click events on "buttonA" and "buttonB".
If I want to trigger functionA and functionB from one "buttonC", how would I do that?
Thanks!

Just call controllers on two different divs
<div ng-controller="controllerA">
<div ng-controller = "controllerB">
<input ng-click="functionA();functionB();"/>
</div>
</div>
OR
call one controller controllerA in your routes for your view.
and call another controller controllerB in your view.
.state('app.example', {
url: '/example',
controller: 'controllerA',
templateUrl: 'example.html',
})
<div ng-controller="controllerB">
<input ng-click="functionA();functionB();"/>
</div>
By this, you can access two controllers

Related

define a controller and use twice

I want to user a controller for two separated div and when I do that , it send $http requests twice
How can i use the scope of other controllers?
here is my code :
<div data-ng-controller="productCTRL">
<span ng-model="basket | count"></span>
....Some HTML Code......
</div>
<div data-ng-controller="AuthController">
....Some HTML Code...
</div>
<div data-ng-controller="productCTRL">
<ul ng-repeat="product in products">
<li>{{product.title}}</li>
</ul>
</div>
One approach...
You could use a monolithic controller:
<div data-ng-controller="mainCTRL">
<div data-ng-controller="productCTRL">
<span ng-model="basket | count"></span>
....Some HTML Code......
</div>
<div data-ng-controller="AuthController">
....Some HTML Code...
</div>
<div data-ng-controller="productCTRL">
<ul ng-repeat="product in products">
<li>{{product.title}}</li>
</ul>
</div>
</div>
Then if you make the $http call in mainCTRL instead of productCTRL, it will run just once when the view is rendered. You could then access the data held in mainCTRL from productCTRL via scope inheritance.
Another approach...
You could move the $http call to an angular service or factory. Since these are singletons, only one instance will ever exist and that means that only one $http call would be made when the app is first loaded. You would then store the returned data locally in the service and expose it publicly.
Here is a simple implementation as a factory:
app.factory("productService", function($http){
var products = [];
$http.get("api/products/get-products").then(function(response){
products = response.data;
});
return {
products: products
}
});
If you inject the factory into your productCTRL it will have direct access to the products data:
appController("productCTRL", function(productService){
$scope.products = productService.products;
});
The controller will still be instantiated twice, but it's only going to reassign the $scope.products variable. Most importantly, it no longer makes a redundant call over HTTP to your API.
It looks like you want to access the scope of other controllers-
Three are ways to communicate-
Parent child inherited scope - You have to create a parent controller and child controller can communicate using Parent scope. It is recommended only for tightly coupled controllers.
Event bus - Subscribe can listen on event ($on) and publisher can publish using $emit (current to parent scope can access using $on) or $brodcast (current to child scope can access using $on). Sibling controller can't share the data using this approach. To share the data between sibling controller, you can use $rootScope.broadcast and this event will be listen by all scope including sibling controllers. It is also coupled using event.
Using service - Both controller can share the data using common service because services are singleton.

Use ui-view as the template for state inside ui-router instead of an external template

I have an app that is currently using the angular ui-router module dependency. The only aspect of the ui-router that I'm currently employing is the ability to apply/modify $stateParams to $scope and vice versa so the URL can change the way data is displayed in the controller to a user on arrival (i.e. url?param=something will filter the data by something).
I have the following in my app.config to set the state:
$stateProvider
.state('root', {
url: '/?param',
templateUrl: 'template.html',
controller: 'listController',
params: {
param: {
value: 'something',
squash: true
}
}
});
On my homepage, template.html successfully loads when the app is instantiated as such:
<div ng-app="myApp">
<div ui-view>
</div>
</div>
However, I have reached a roadblock and realize that calling the template from within templateUrl isn't going to work, as this app is being built inside another framework and therefore needs to be called from within the homepage itself to access its full capabilities.
Being a noob at AngualrJS, I was wondering if anyone can tell me what the best way is to accomplish this while still keeping the logic of $stateParams and other ui-router capabilities intact for the future.
For instance, could I just remove the templateUrl parameter from my state and call the controller directly inside the ui-view like this:
<div ng-app="myApp">
<div ui-view>
<div ng-controller="listController">
do something
</div>
</div>
</div>
I also looked into changing the entire logic from using ui-router to simply using the $location service but I'm wondering if there is a way to accomplish this without needing to over-do everything.

How to prevent losing data when moving from one state to another in multi-step form?

I am new to web programming and especially to AngularJS.
So maybe my question will seem naive to some of you.
I'm developing a single page application using angular-ui-router.
I have created a multi-step form that contains 3 states:
(function () {
"use strict";
angular.module("sensorManagement", ["ui.router", "ngAnimate", "ngResource", "toaster"])
.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterPorvider) {
$urlRouterPorvider.otherwise("/Sensor/Home");
$stateProvider
.state("MultiStepForm", {
url: "/Sensor/MuiltyStepForm",
templateUrl: "/app/MultiStepForm/MuiltyStepForm.html",
})
.state('MultiStepForm.step1', {
url: '/step1',
templateUrl: '/app/MultiStepForm/FormStep1.html'
})
.state('MultiStepForm.step2', {
url: '/step2',
templateUrl: '/app/MultiStepForm/FormStep2.html'
})
.state('MultiStepForm.step3', {
url: '/step3',
templateUrl: '/app/MultiStepForm/FormStep3.html'
});
}]);
})();
Here is the HTML code:
<!-- form.html -->
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-multiple-step">
<div class="page-header text-center">
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".step1"><span>STEP1</span></a>
<a ui-sref-active="active" ui-sref=".step2"><span>STEP2</span></a>
<a ui-sref-active="active" ui-sref=".step3"><span>STEP3</span></a>
</div>
</div>
<form id="single-form">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
</div>
</div>
As you can see I have 3 states and each state has it's own view. The views have multiple elements (textboxes and checkboxes).
When the user enters some data for the STEP1 view and moves to the next step (STEP2 or STEP3) then at some point goes back to STEP1 all data is deleted. I checked with fiddler and can see that when I move from one state to another a call is made to the server and a new view generated.
My question is how can I prevent the lose of data when I move from one state to another? Do I have to use caching? Or maybe there is another way to prevent server calls and keep the data alive until the submit button clicked.
When you feel you have to save data across your controllers in your app. you should use a service.
app.factory('sharedDataService', function ($rootScope) {
console.log('sharedDataService service loaded.');
// do something here that can be shared in other controller
});
//pass this service in your controller to use it there
app.controller('Controller2', ['$scope', 'sharedDataService', function ($scope, sharedData) {
console.log('Controller2 controller loaded.');
//get data from shared service
}]);
find a useful Fiddle here
Cheers if it helps!
I think what you need to do is share you $scope between the parent and child stats. here is the stackoverflow post with good example. https://stackoverflow.com/a/27699798/284225

How to update variables in ng-include view

I have a form and a view that shows data from that form. I want to separate form and view (which will be more that one).
Here is my code:
<div data-ng-controller="dataController" class="container">
<div data-ng-view></div>
<div ng-include="templates.simple" scope="data"></div>
</div>
And the included view shows initial data good, but does not react on any data change. How do I fix it?
data is and object with some fields.
templates.simple is a scope variable with template url
Code example: http://plnkr.co/edit/ibrsBaq8osYuEODGiM6O
The reason why binding is not working is you are reinitalizing an createDataController which is again creating data object for that ng-view template. This could be solve by removing createDataController controller from route.
Code
$routeProvider
.when('/', {
templateUrl: 'form.html',
//controller: 'createDataController'
})
Plunkr Here
Update
Other way would be if you want to load your controller twice still it doen't make any sense though. You could do this by writing ng-init on outside div, Instead of declaring that variable from controller.
<div data-ng-controller="createDataController" ng-init="data = {name: 'texy'}">
<div data-ng-view></div>
<div data-ng-include="'template.html'"></div>
</div>
Updated Plunkr

Changing $scope variable value in controller not changing value on view

I am working on Cordova tool and angularjs for my application.
cordovaApp.controller("VacationCtrl", function ($scope, $http, $location) {
$scope.tempdate = "2222";
$scope.ruleDetails = function () {
$scope.tempdate = "3333";
}
});
view 1
<div ng-controller="VacationCtrl">
<a ng-repeat="data in rules" ng-click="ruleDetails()" class="summaryListBorder" href="#detailVacationRule">
</a>
</div>
view 2
<div ng-controller="VacationCtrl">
{{tempdate}}
</div>
In above given code, I sat value of $scope.tempdate to "2222". When I am click on link, it calls ruleDetails() and set $scope.tempdata = "3333". But when the new page is open with ng-view, it shows only old value, i.e. "2222". I want to change it with "3333". I have tried with $scope.$apply() too.
Thanks.
Every ng-controller attribute creates a new instance of the controller, which won't share the same scope as other instances. You want to wrap both divs in a single controller instance, like:
<div ng-controller="VacationCtrl">
<div>
<a ng-click="ruleDetails()" href="#detailVacationRule">
</a>
</div>
<div>
{{ tempdate }}
</div>
</div>
If you need separate controllers, then you want to move common functions/fields into a service, which operates as a singleton so you can use it to share information between controllers. Or you could contain the separate controller instances in a parent controller, which will hold common fields and can be accessed through each controller's scope.

Resources