Change values between views - Ionic Controller - angularjs

Im using the same controller for 2 views in Ionic, because, its the same information I need.
Let me explain, at the view "config" I use ConfigCtrl, at this view I had a language option, when ng-clicked go to "languages", choose a lang and back to "config" with the same controller ConfigCtrl.
I use radio button component, and if I spec the value on controller, Its ok, the data has change, but at the "config" view its not updating!
Check the code.
<span class="item-note">
{{data.lang| translate}}
</span>
/\ Config.html
<ion-radio ng-model="data.lang" ng-click="saveLanguage()" ng-value="'pt_br'">{{'pt_br'| translate}}</ion-radio>
<ion-radio ng-model="data.lang" ng-click="saveLanguage()" ng-value="'en'">{{'en'| translate}}</ion-radio>
/\ Languages.html
.controller('configurationCtrl', ['$scope', '$rootScope', '$stateParams', 'UtilsFactory', // TIP: Access Route Parameters for your page via $stateParams.parameterName
function ($scope, $rootScope, $stateParams, UtilsFactory) {
$scope.data = {};
//Language scope
$scope.data.lang = $rootScope.language;
$scope.saveLanguage = function () {
$rootScope.language = $scope.data.lang;
setAnimation('right-animation', '/side-menu/configuration')
}
}])
/\ ConfigCtrl
If I debug the saveLanguage() when clicked its saves, change the value of data.lang, back to the Config.html view, but the value didnt change at the view of 'Config.html", I need to 'refresh' this field on a view, I cant refresh all the page because it will reload the $scope.data.lang

Related

Read Data From One Controller To Another

I've two controllers and two views in ASP.NET MVC project. My requirement is to pass data from one controller to another on ng-click that should reflect in another view (As well from another controller). Simple! I know, it could be done using service but I was preferring for testing purpose $broadcast and $on. So I tried the following:
app.controller('FirstController', function ($rootScope, $scope, productService) {
$scope.showData = function (m) { //This is the event on which I'll get data in another controller as well in another view
alert(m); //This works and gets a name from the first view
$rootScope.$broadcast('sample', $scope.m); //This is what I am using to deliver in another controller
}
});
app.controller('SecondController', function ($scope) {
$scope.$on('sample', function (events, d) {
alert(d);
})
In another view, I used something like this:
<div ng-app="app" ng-controller="SecondController">
<ul class="nav navbar-nav">
<li> Product {{ m }}</li>
</ul>
</div>
Actually I am doing this all for demo purpose. But unfortunately, the above doesn't work. Am I missing something?
Update 1 - See the updated code:
app.controller('FirstController', function ($rootScope, $scope, productService) {
$scope.showData = function (m) { //This is the event on which I'll get data in another controller as well in another view
alert(m); //This works and gets a name from the first view
$timeout(function () {
$scope.$broadcast('sample', m);
});
}
});
app.controller('SecondController', function ($scope) {
$scope.$on('sample', function (events, d) {
alert(d);
})
In your scenario it will not work in one case:
You call $rootScope.$broadcast('sample', $scope.m); before
$scope.$on() is registered to listen on 'sample event a.e. before SecondController is created.
If you know that SecondController is created , you can wrap $rootScope.$broadcast('sample', $scope.m); with $timeout. a.e.:
$timeout(function(){
$rootScope.$broadcast('sample', $scope.m);
});
In this case $broadcast execution will be moved to end of events queue a.e. before next digest cycle that will be guarantee that Second Controller has been created and $scope.$on() is registered.
It's not entirely clear how you are using the second view & controller. Is it somewhere within the template that FirstController is assigned to? Seeing the template assigned to FirstController would help clarify. In any case, I've attached a simple plunker which shows how you can broadcast an event from a button click to a second controller.
https://plnkr.co/edit/KzNftVAYwPuCvsnflIz

Select Dropdown not displaying $scope value in model

I've used angular plenty of times, but can't seem to spot the issue I'm getting:
I pass through an ID like so as a clickable link within a repeater:
<td data-title="'Company Name'" sortable="'CompanyName'"><a ui-sref="Locations({company_id: row.CompanyID})">{{row.CompanyName}}</a> </td>
The value is correctly passed through and received by the relevant controller I use a query string service to get the relevant filters. The console.log correctly shows the correct value. However, it is not selecting the relevant value within the select dropdown:
angular.module('app').controller("LocationsController", ['$timeout',
'$scope', '$http', 'QueryStringService', 'NgTableParams', '$location',
function ($timeout, $scope, $http, QueryStringService, NgTableParams,
$location) {
var default_filters = { location_name: "", address_1: "", company_id: "" };
$scope.filterBy = QueryStringService.getFilters(jQuery.extend(true, {}, default_filters));
console.log($scope.filterBy.company_id);
}
// Displayed on relevant view
<select ng-model="filterBy.company_id" ng-options="option.CompanyID as option.CompanyName for option in companies" class="form-control form-control-query">
<option value="">All</option>
</select>
Can anyone notice anything?
I think you are facing a controller scope issue:
You are setting a variable in a controller instance, and trying to get it from another instance.
The fact is that a controller is instancied for each page, even if it is the same controller name (that may be confusing).
You should use a service to store this variable (for example your QueryStringService), and access it from your other page.
Here is a JSFiddle demo.

Angular: Service to Pass Data To Another Controlelr

So, I have a ng-repeated list of items as such.
<li><a ng-click="{{person.id}}">Name of Person</a></li>
I would like to create a service wherein, on click, I can collect that person.id and pass it to another controller in a different route.
This would normally be very simple by just using the url and route params, however, in this case it is important that the person.id not be exposed within the browser url.
-- More Context
Whether service or not, I am needing to extract a {{person.Id}} that is data available via an ng-repeat on a list page of persons.
On click, I move from a persons controller to a new route with a "person" controller. I need that "person" controller to be able to pull the {{Person.ID}} that was clicked on the previous route in order to look up that person in a DB.
Any help would be really great!
Services aren't meant to interact directly with DOM elements. DOM should interact with directives/controllers. Controller should interact with models.
This example below demonstrates sending data from controller 1 to myFactory and then controller 2 gets it the value from myFactory.
angular
.module('app', [])
.factory('myFactory', myFactory)
.controller('myCtrl1', myCtrl1)
.controller('myCtrl2', myCtrl2);
function myFactory() {
var fromSender = null;
return {
setSender: function(sender) {
fromSender = sender;
},
getSender: function() {
return fromSender;
}
};
}
function myCtrl1(myFactory) {
var vm = this;
vm.setSender = myFactory.setSender;
}
function myCtrl2(myFactory) {
var vm = this;
vm.getSender = myFactory.getSender;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="app">
<div ng-controller="myCtrl1 as ctrl1">
Controller 1: <br>
<button ng-click="ctrl1.setSender('from controller 1')">Send to myFactory</button>
</div>
<hr>
<div ng-controller="myCtrl2 as ctrl2">
Controller 2: <br>
value from ctrl1 via myFactory: {{ctrl2.getSender()}}
</div>
</div>
All services in Angular are singletons. So if you inject personService or something like that, in multiple controllers, then those controllers will be using the exact same object. So if you set a value on that service, then the other controllers will be able to see it.
With more code and context, I'll be able to give a more specific example.

Angular - Template not refreshed with data bound from two different scopes to the same service

I bind data of two different scopes to the same common service data. When I update the data through controller 1, the data in controller 2 is not refreshed in template.
Example showing the issue :
<body ng-app="demoShareBindApp">
<div ng-controller="FirstCtrl as first">
Set share data to : <a href ng-click="setShareDataTo('Me')">"Me"</a>
- <a href ng-click="setShareDataTo('Myself')">"Myself"</a>
- <a href ng-click="setShareDataTo('I')">"and I"</a>
</div>
<div ng-controller="SecondCtrl as second">
Text entered : {{sShareData}}
<br>
<br><a href ng-click="revealShareData()">Reveal data</a>
</div>
<script src="bower_components/angular/angular.js"></script>
<script>
angular
.module('demoShareBindApp', [])
.service('myService', function () {
return {
shareData: null
}
})
.controller('FirstCtrl', ['$scope', 'myService', function ($scope, myService) {
$scope.setShareDataTo = function(content) {
myService.shareData = content;
};
}])
.controller('SecondCtrl', ['$scope', 'myService', function ($scope, myService) {
$scope.sShareData = myService.shareData;
$scope.revealShareData = function() {
console.log(myService.shareData);
}
}]);
</script>
</body>
The Text entered : {{sShareData}} is never updated whereas clicking "Reveal data" shows the right share data in console.
I can't find any clue in other SO post on this particular subject. I guess it could be a matter of "$watch/$digest" but I can't figure out what is really going on here.
Any detailed explanation welcome !
You are sharing data through service. When data in changed under first controller, you set this updated data to service but second controller does not know that shared data referenced by service has changed, so we need to notify the second controller that data has changed or we can shared data through events
I created a fiddle, check it
https://jsbin.com/midebu/edit?html,js,output
First approach. Using service
$scope.setShareDataTo = function(content) {
myService.shareData = content;
$rootScope.$broadcast('datacChanged');
};
In second cntroller
$rootScope.$on('dataChanged', function(){
// get updated data
$scope.sShareData = myService.shareData;
})
Other way is that, we do not need to use service , we can simply pass that shared data using events
$scope.setShareDataTo = function(content) {
$rootScope.$broadcast('datacChanged', content);
};
And in Second controller
$rootScope.$on('dataChanged', function(event, data){
// get updated data
$scope.shareData = data;
})

Propagating model changes to a Parent Controller in Angular

I have a an angularJS application and would try to simulate a Asana.com feature.
The scenario is the following:
I have a MainController for my application in the body tag, and inside this controller I populate my names in my sidebar:
.controller('MainController', ['$scope', 'NamesService', function($scope, NamesService) {
$scope.names = NamesService.query();
...
};
When I click on any name (for example, Anna), my application change the route and in inject the name-edit.html template in my ng-view, represented by the content area on the picture above. I have a input used to change from Anna to Carol and a update button. When I hit the update button, It fires a function that updates in my database, changes Anna to Carol in my content area (represented by the yellow arrow position) but doesn't change the red arrow position in my sidebar.
I tried to call the following code again inside my success update callback, but doesn't work
$scope.names = NamesService.query();
I'd like to know how to propagate the child controller to the parent controller, changing Anna to Carol inside $scope.names. Is it possible to do this, without reloading $scope.names?
You could use event system of Angular using $scope.$emit('eventName', eventData) un your child controller to pass data up on the hierarchy.
//child, assuming you have promise callback
NamesService.query().then(function(data){
$scope.$emit('eventName', data)
})
And in your parent controller have the following
//parent
$scope.$on('eventName', function(event, data){
$scope.names = data;
})

Resources