var myApp = angular.module('myApp', []);
myApp.factory('Data', function() {
return {message: "I'm data from a service"}
})
function FirstCtrl($scope, Data){
$scope.data = Data;
}
function SecondCtrl($scope, Data){
//I want to send a string to the service so that the view associated with FirstCtrl is updated.
}
Ok, lets take this code for example. How would one set the message string from inside SecondCtrl so that the view binded with FirstCtrl is updated?
You may share data between controllers using a service (factory), but you will not use $scope directly.
Please refer to this video for a demonstration:
https://egghead.io/lessons/angularjs-sharing-data-between-controllers
Thumbs up for egghead \o/
Edit:
var myApp = angular.module('myApp', []);
myApp.factory('Data', function() {
return {message: "I'm data from a service"}
})
function FirstCtrl($scope, Data){
$scope.data = Data;
}
function SecondCtrl($scope, Data){
$scope.data = Data;
// Simply set the message or bind it to an input on your view:
$scope.data.message = 'new value'
}
Here is a demo: http://jsfiddle.net/suhvtr5r/
If this doesn´t work, please share your views with us
One thing you can do is to create another parent controller like this,and put common things to both controllers
<div ng-controller="parentController">
<div ng-Controller="pageOneController">
<input placeholder="{{placeholder}}" type="text" />
</div>
<div ng-Controller="pageTwoController">
<--other html-->
</div>
</div>
app.controller('parentController', ['$scope', function($scope) {
$scope.placeholder = "this is common to both child controllers";
}]);
If you want to do that you need getter and setter in your service here is the fiddle that do the trick for you :
HTML:
<div ng-app="myApp">
<div ng-controller="FirstCtrl">my first cotroller : {{data.message}}</div>
<div ng-controller="SecondCtrl">my second controller :
<input type="text" ng-model="data.message" ng-change="update()">
</div>
</div>
Angular:
var myApp = angular.module('myApp', []);
myApp.factory('Data', function () {
return {
message: '',
get: function () {
alert("DasdaS");
return this.message;
},
set: function (secondCtrlStr) {
this.message = secondCtrlStr;
}
};
})
function FirstCtrl($scope, Data) {
$scope.data = Data;
}
function SecondCtrl($scope, Data) {
$scope.update = function () {
Data.set($scope.data.message);
};
}
Related
i have a html like below
<a class="event_detail_btn_a" ng-click="foo()"></a>
following is my controller
onsenApp.controller("EventDetailController", function ($scope) {
$scope.foo = function(){
alert("foo!");
var options = {
data: {
title: 'Another Page'
}
};
};
});
i want to pass "options" variable to another controller from this controller.
how can i do it ?
Use $broadcast to pass data between controllers.
In the example add() is defined in Controller1 which is passed to Controller2 after 2 secs.
angular
.module("app", [])
.controller("Controller1", function($scope, $rootScope, $timeout){
var add = function(a, b) {
return a + b;
}
$timeout(function(){
$rootScope.$broadcast("Add function", add);
}, 2000);
})
.controller("Controller2", function($scope, $rootScope, $timeout){
$scope.$on("Add function", function(event, add) {
$scope.sum = add(3, 4);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="Controller1">
<span>Add function defined in Controller1</span><br /><br />
</div>
<div ng-controller="Controller2">
<span ng-show="sum">3 + 4 = {{ sum }}</span>
<span ng-show="!sum">Controller2 waiting for add function...</span><br />
</div>
</div>
Best way to create a service OR a factory and inject in both controllers like below:
var myApp = angular.module('myApp', []);
myApp.factory('MyService', function() {
var options = {
data: {
title: 'Another Page'
}
};
return {
options
};
});
myApp.controller('FirstCtrl', function($scope, MyService) {
$scope.options = MyService.options;
});
myApp.controller('SecondCtrl', function($scope, MyService) {
$scope.options = MyService.options;
});
You want to pass data to another controller, the way i am getting it is :
onsenApp.controller("EventDetailController", function ($scope) {
$scope.foo = function(){
alert("foo!");
var options = {
data: {
title: 'Another Page'
}
};
this is one way you can achieve this using event push-page with it you send data.
myNavigator.pushPage('xyz.html',
{myData: options} );
}
};
});
onsenApp.controller("SecondController", function ($scope) {
here you can get your desired data
$scope.options = myNavigator.getCurrentPage().options.myData;
});
I have a view for SidebarController like below -
<a ng-click="reachMe($event);$event.preventDefault()" ng-href="#/app/hello">
Before going to the link I want to call reachMe() to check some changes on page and need to show an alert if any changes made
function SidebarController($rootScope, $scope, $state, $location, SidebarLoader){
$scope.reachMe = function(event){
//here I want to call function isPageChanged() from StaticPageController
//something like this
// if StaticPageController.isPageChanged() return true
// then show alert
// else
// $location.url($href)
}
}
Update 1 :
Not sure about this, But give it a try.
<div ng-app="testApp" ng-controller="ControllerOne">
<button ng-click="methodA();"> Call Another Controller</button>
</div>
<script>
var app = angular.module('testApp', []);
app.controller('ControllerOne', function($scope, $rootScope) {
$scope.reachMe = function() {
var arrayData = [1,2,3];
$rootScope.$emit('callEvent', arrayData);
if($rootScope.isChanged){
// Show Alert
}else{
//Go to route
}
}
});
app.controller('ControllerTwo', function($scope, $rootScope,$state) {
$scope.checkSomethingChanged = function() {
alert("Hello");
$rootScope.isChanged = true;
}
$rootScope.$on('callEvent', function(event, data) {
console.log(data);
$scope.checkSomethingChanged();
});
});
Following method worked for me perfectly :
<div ng-app="testApp" ng-controller="ControllerOne">
<button ng-click="methodA();"> Call Another Controller</button>
</div>
<script>
var app = angular.module('testApp', []);
app.controller('ControllerOne', function($scope, $rootScope) {
$scope.methodA = function() {
var arrayData = [1,2,3];
$rootScope.$emit('callEvent', arrayData);
}
});
app.controller('ControllerTwo', function($scope, $rootScope) {
$scope.reachMe = function() {
alert("Hello");
}
$rootScope.$on('callEvent', function(event, data) {
console.log(data);
$scope.reachMe();
});
});
</script>
A controller is not the right concept for sharing functionality. Use a Factory or Service for that.
var logicFactory = function () {
return {
methodA: function () {
},
methodB: function()
{
}
};
}
You can then inject that factory into each controller where it is needed like:
var ControllerA = function ($scope,logicFactory) {
$scope.logic = logicFactory;
}
ControllerA.$inject = ['$scope', 'logicFactory'];
Another option is to use the broadcast/emit Patern. But I would use that only where really necessary:
Usage of $broadcast(), $emit() And $on() in AngularJS
I have a main controller and nested controllers within it. In the main controller I have defined object by async query to the service, and try to use the object in the nested controller. But in the object in the nested controller is empty, cause it fires before it will be updated in the main controller.
As I understand, asyncronous query should updates the scope after data obtain?
.controller('MainController', ['$scope', function($scope) {
$scope.uData = {};
$scope.uDataCurrent = {};
$scope.usersData = usersFactory.getUsersData().query(
function(response) {
$scope.uData = response;
$scope.uDataCurrent = $filter('filter')($scope.uData, {'user':$scope.myuser});
$scope.uDataCurrent = $scope.uDataCurrent[0];
},
function(response) {
$scope.message = "Error: "+response.status + " " + response.statusText;
});
})]
.controller('NestedController', ['$scope', function($scope) {
console.log($scope.uDataCurrent); // returns empty object
}])
Service:
.service('usersFactory', ['$resource', 'baseURL', function($resource,baseURL) {
this.getUsersData = function(){
return $resource(baseURL+"/index.php?app=users&format=raw&resource=user",null, {'update':{method:'PUT' }});
};
}])
You could use $scope.$watch.
angular.module("App", [])
.controller("OuterCtrl", ["$scope", "$timeout", function($scope, $timeout) {
$scope.users = null;
$timeout(function() {
$scope.users = ["John", "Jack"];
}, 500);
}]).controller("InnerCtrl", ["$scope", function($scope) {
$scope.changeCount = 0;
// TODO: Bad practice to rely on outer scopes here as its not enforced
// to have an OuterCtrl scope as parent scope. In this example every
// occurrences of InnerCtrl is embedded in an OuterCtrl in the html
$scope.$watch("users", function(newValue, oldValue) {
// This code runs when the users array is changed
$scope.changeCount++;
});
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.js"></script>
<div ng-app="App">
<div ng-controller="OuterCtrl">
<div ng-controller="InnerCtrl">
<div>Change count: {{changeCount}}</div>
<div>Users</div>
<div ng-hide="users"> Loading...</div>
<ul>
<li ng-repeat="name in users">{{name}}</li>
</ul>
</div>
</div>
</div>
(function() {
angular
.module('myApp.home', [])
.factory('myService', function($http) {
return {
getInfo: function() {
// return something
}
};
})
.controller('HomeController', function($scope, $routeParams, myService) {
var my = this;
var sid;
myService.getInfo().success(function(data) {
my.id = data.id;
//sid= my.id;
});
//my.id = sid;
});
})();
I'm trying to access the variable id in my view. But I'm not able to do so. I'm getting an undefined variable error.
I even tried to declare a variable sid globally so that it can be accessed from everywhere and I tried assigning value to it as well but that effort also didn't bring up any results.
My services are working fine and they are returning data. I'm trying to use the id in my view but don't know where I messed it up.
Any help?
EDIT
And my HTML is like this:
<div data-id="my.id"></div>
If you want to use it in your view you have to bind it to a scope e.g. $scope.id - check this link for reference.
Below is your html, how it should be.
<div ng-app="app" ng-controller="HomeController as home">
<div data-id="home.id">{{home.id}}</div>
</div>
Below is how your controller part.
angular.module('app', [])
.controller('HomeController', function () {
this.id = "someValue";
});
http://jsfiddle.net/grdmLfxt/
use controllerAs : vm then you can access vm.id in your view.
HTML
<div ng-app="app" ng-controller="HomeController as vm">
<div data-id="vm.id">{{vm.id}}</div>
</div>
Controller
.controller('HomeController', function () {
var vm = this;
vm.id = "someValue";
});
for more info read this
small change in javascript code and html. try this.
Javascript
(function() {
angular
.module('myApp.home', [])
.factory('myService', function($http) {
return {
getInfo: function() {
// return something
}
};
})
.controller('HomeController', function($scope, $routeParams, myService) {
var my = this;
var sid;
myService.getInfo().success(function(data) {
$scope.id = data.id; // changed from my.id to $scope.id
//sid= my.id;
});
//my.id = sid;
});
})();
HTML
<div data-id="id"></div>
I'd like to be able to access a controller variable inside a function of this controller.
Why is the following code throwing an error into the console instead of showing the input value ?
JS:
var app = angular.module("app", []);
app.controller("TestCtrl", function($scope) {
$scope.string = "";
$scope.click = function() { // I've also tried with $scope in parameter
console.debug(string); // and $scope.string here, same issue
}
});
HTML :
<div ng-app="app" ng-controller="TestCtrl">
<input type="text" ng-model="string"></input>
<button ng-click="click()">Click me !</button>
</div>
JSFiddle
remove $scope from the argument in you click function, and use it inside the function - see below and updated fiddle
app.controller("TestCtrl", function($scope) {
$scope.string = "";
$scope.click = function() {
console.debug($scope.string);
}
});
You can try another approach:
app.controller("TestCtrl", function($scope) {
this.string = "";
var that = this;
$scope.click = function() {
console.debug(that.string);
}
});
See on JSFiddle:
http://jsfiddle.net/qn47syd2/