How to create controller inside a controller in angular js - angularjs

I would like to create a controller inside a controller in angular Js. But my code is not working. Please help me on this.
Controller :
app.controller('MainController',function($rootScope,$scope){
console.log('MainController Created');
$scope.test = "Success";
app.controller('InnerController',function($scope){
console.log('Inside the InnerController');
console.log($scope.test);
})
});
below is my html body:
<body>
<div ng-app="myApp" ng-controller="MainController">
Enter your Name :
<input type="text" ng-model="name" placeholder="your name">
<div ng-show="name">
<h2>This is called Two way binding :: {{name}}</h2>
</div>
<div ng-controller="InnerController">
<h2>{{name}}</h2>
</div>
</div>
</body>

You should put your inner controller declaration outside of MainController, because they both need to be initialised before html is parsed
app.controller('MainController',function($rootScope,$scope){
console.log('MainController Created');
$scope.test = "Success";
});
app.controller('InnerController',function($scope){
console.log('Inside the InnerController');
console.log($scope.test);
});

in html like you did main is a father controller of innercontroller
but in angular it is controller with himself like that:
app.controller('MainController',function($rootScope,$scope){
console.log('MainController Created');
$scope.test = "Success";
});
app.controller('InnerController',function($scope){
console.log('Inside the InnerController');
console.laog($scope.test);
})

You cannot create a controller inside another controller. But you can nest DOM elements with different controllers inside each other. So you should change your controllers' declaration to this:
app.controller('MainController',function($rootScope,$scope){
console.log('MainController Created');
$scope.test = "Success";
});
app.controller('InnerController',function($scope){
console.log('Inside the InnerController');
console.log($scope.test);
});
Pay attention that test is still available in the InnerController.

Related

Passing data from html div tag to controller in AngularJS

I have a div in my html. Inside the div I am invoking a controller. I need to pass some data from div to the controller. I don't have any other html element in div like input fields/buttons etc.
<div ng-controller="writeLoadTimeController">
<!--adding this controller to send the page load time to server-->
$scope.loadTime=$window.performance.timing.domContentLoadedEventEnd-$window.performance.timing.navigationStart;
</div>
How do I pass the value of the loadTime field to the controller.
you can try:
<div id="loadTime" ng-controller="writeLoadTimeController" ng-load="someFunction()">
</div>
and controller:
$scope.someFunction = function(){
$scope.loadTime=$window.performance.timing.domContentLoadedEventEnd-$window.performance.timing.navigationStart;
}
1: You can add onload event to the div and call a function which will calculate the loadTime for you. It should be like this.
you html:
<div id="loadTime" ng-controller="writeLoadTimeController">
</div>
and the controller:
app.controller("writeLoadTimeController", function($scope){
$scope.loadTime ="";
document.getElementById("loadTime").addEventListener('onload', onloadHandler);
function onloadHandler(){
$scope.loadTime=$window.performance.timing.domContentLoadedEventEnd-$window.performance.timing.navigationStart;
}
});
Then you can use {{loadTime}} in the html.
2: You can avoid adding onload listener and do the following:
you html:
<div id="loadTime" ng-controller="writeLoadTimeController">
</div>
and the controller:
app.controller("writeLoadTimeController", function($scope){
$scope.loadTime ="";
$scope.loadTimeCalculator = function(){
$scope.loadTime=$window.performance.timing.domContentLoadedEventEnd-$window.performance.timing.navigationStart;
}
$scope.loadTimeCalculator();
});
It will call loadTimeCalculator() function when the writeLoadTimeController is called.
Hope this will help you:)

How to access angularJS controller as variables?

How to define the value for controller as elements inside custom directive link function?
HTML
<div ng-controller="myCtrl as ctrl">
<input type="text" ng-model=ctrl.inputvalue" my-directive/>
<button value="submit" ng-disabled="ctrl.disable"/>
</div>
JS
app.controller('myCtrl',function(){
var vm = this;
vm.inputValue = 'Qwerty';
});
app.directive('myDirective',function(){
return{
require:'ngModel',
link:function(scope,elements,ngModelCtrl){
//How to access ng-diasbled value here
});
}
});
Inside link function write as scope.ctrl.disable to access the disable value.
app.directive('myDirective',function(){
return{
require:'ngModel, ^myCtrl',
link:function(scope,elements,ctrls){
var d = ctrls[1].disable
});
}
});

Controller triggered via factory

I am still a novice with angular. I have asked a question similar to this before, but it seems to be a different issue at work here.
I have two controllers and a factory sharing information between them. I have two separate divs using two different controllers to show / hide using ng=show;
HTML
<div id=main>
<div ng-controller="Ctrl1">
<div ng-show="var1">Hidden Stuff</div>
</div>
<div ng-controller="Ctrl2">
<div ng-show="var1">More Hidden Stuff</div>
</div>
</div>
Both use the same var for ng-show, shared by a factory
JS Factory
app.factory('Srvc', function($rootScope) {
var Srvc = {};
Srvc.var1;
return Srvc;
});
JS Controllers
app.controller('Ctrl1', function($scope, Srvc) {
$scope.var1 = false;
if (user interacts with html in div with ng-controller="Ctrl1") {
$scope.var1 = true;
Srve.var1 = $scope.var1;
}
});
app.controller('Ctrl2', function($scope, Srvc) {
$scope.var1 = Srvc.var1;
if ($scope.var1 === true) {
update HTML in div with ng-controller="Ctrl2"
although I shouldn't need to do this really should I?
}
});
So from what I can tell the factory works ok, the data is saved in the factory Srvc.var1. However when I pass the data true to Srvc.var1 I cannot seem to get Ctrl2 to 'trigger' and update its html with ng-show=true
One way to solve this problem without explicitly creating a watcher, is to wrap var1 in an object inside the service and then pass this object as a $scope variable for both Ctrl1 and Ctrl2 controllers.
DEMO
Javascript
.factory('Svc', function() {
var service = {
data: {}
};
// If you perform http requests or async procedures then set data.var1 here
service.data.var1 = true;
return service;
})
.controller('Ctrl1', function($scope, Svc) {
$scope.data = Svc.data;
})
.controller('Ctrl2', function($scope, Svc) {
$scope.data = Svc.data;
});
HTML
<div id="main">
<div ng-controller="Ctrl1">
<div ng-show="data.var1">Hidden Stuff</div>
<button type="button" ng-click="data.var1 = true">Set data.var1 to true</button>
<button type="button" ng-click="data.var1 = false">Set data.var1 to false</button>
</div>
<hr>
<div ng-controller="Ctrl2">
<div ng-show="data.var1">More Hidden Stuff</div>
<button type="button" ng-click="data.var1 = true">Set data.var1 to true</button>
<button type="button" ng-click="data.var1 = false">Set data.var1 to false</button>
</div>
</div>
So it seems I need to $watch the service for a change within the controller.
Original answer is here.
app.controller('Ctrl2', function($scope, Srvc) {
$scope.$watch(function () {
return Srvc.var1;
},
function(newVal, oldVal) {
$scope.var1 = newVal;
}, true);
});
I think setting Var1 to $rootScope instead of Srvc should work, just call $scope.$root.$digest() after updating var1.
and use ng-show=$root.Var1 in view.

Why isn't the Angular ng-click event firing?

I've been following a course to learn angularjs and I can't seem to get a simple ng-click binding to work.
HTML:
<body ng-controller="MainController">
<div ng-app="githubViewer">
<h1>{{message}}</h1>
<div>{{ error }}</div>
{{username}}
<form name="searchUser">
<input type="search" placeholder="Username to find" ng-model="username" />
<input type="submit" value="Search" ng-click="search(username)" />
</form>
<div>
<div>{{user.name}}</div>
<img ng-src="http://www.gravatar.com/avatar/{{user.gravatar_id}}" title="{{user.name}}">
{{user.gravatar_id}}
</div>
</div>
</body>
Javascript:
(function () {
var module = angular.module("githubViewer", []);
var MainController = function ($scope, $http) {
var onUserComplete = function (response) {
$scope.user = response.data;
};
var onError = function (reason) {
$scope.error = "Could not fetch the user";
$scope.reason = reason;
};
$scope.username = "angular";
$scope.message = "Github Viewer";
$scope.search = function (username) {
$http.get("https://api.github.com/users/" + username)
.then(onUserComplete, onError);
};
};
module.controller("MainController", MainController);
}());
When you click the search button (search for username "odetocode" or "robconery") it is supposed to display an image but the click event does not seem to be firing. I have searched the documentation and looked over the course again but I can't see what I'm doing wrong.
I'm currently using version 1.2.16 of angularjs.
You have the ng-controller declaration outside of the ng-app declaration right now:
<body ng-controller="MainController">
<div ng-app="githubViewer">
It should be the other way around, or have both on the same element
<body ng-app="githubViewer" ng-controller="MainController">
<div>
AngularJS evaluates your code, and checks for any directives you have declared from the ng-app element down, including the element it is declared on; This currently is missing the ng-controller directive, as it is placed on a parent element of the ng-app element.
You need to put the controller within the context of the module to have it within its scope.
Like so
<body ng-app="githubViewer" ng-controller="MainController">
Demo here

Very simple ng-model watch not working

Here is the jsfiddle.
http://jsfiddle.net/CLcfC/
code
var app = angular.module('app',['']);
app.controller('TestCtrl',function($scope){
$scope.text = 'Change Me';
$scope.$watch('text',function(){
alert('Changed !');
});
})
HTML
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="TestCtrl">
<input type="text" ng-model='text'/>
<span>{{text}}</span>
</div>
</div>
I am not able to see the change in $scope.text. Please help.
This is so easy but what am I missing?
Change the module creation to this, make sure you don't put a empty string in the []. (Obvious the empty string is not a module that can be injected.)
var app = angular.module('app', []);
Demo: http://jsfiddle.net/MWa66/
Your JavaScript file loads after the AngularJS initialization and that's why it fails to find your module. In order to fix it change the initialization to a manual initialization.
First change your HTML and remove the ng-app directive:
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div id="appRoot">
<div ng-controller="TestCtrl">
<input type="text" ng-model='text'/>
<span>{{text}}</span>
</div>
</div>
Then go to your JavaScript and use angular.bootstrap method to manually attach your module:
var app = angular.module('app',[]);
app.controller('TestCtrl',function($scope){
$scope.text = 'Change Me';
$scope.$watch('text',function(){
alert('Changed !');
});
});
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('appRoot'), ['app']);
});
You can find more help on manual AngularJS initialization here.
Thank you! I solved this annoying thing!
The solution that worked for me was that I use angular UI router and there I had used the following code
.state('app.monimes', {
url: "/monimes",
views: {
'menuContent' :{
templateUrl: "templates/monimes.html",
controller: 'sampleCtrl'
}
}
})
so then in the controller I had
/***
*
*Controller for tests..
*/
.controller('sampleCtrl',['$scope','sampleService', function($scope, $sampleService) {
$scope.username="em";
// Watch for changes on the username property.
// If there is a change, run the function
$scope.$watch('username', function(newUsername) {
// uses the $http service to call the GitHub API
// //log it
$scope.log(newUsername);
// and returns the resulting promise
$sampleService.events(newUsername)
.success(function(data, status, headers) {
// the success function wraps the response in data
// so we need to call data.data to fetch the raw data
$scope.events = data.data;
});
},true);
}
]);
and in the view I had
<div>
<label for="username">Type in a GitHub username</label>
<input type="text" ng-model="username" placeholder="Enter a GitHub username, like a user" />
<pre ng-show="username">{{ events }}</pre>
</div>
but that didn't work.
so I added ng-controller="sampleCtrl"
to the div and now it works :D
so that means that the view is loaded after the controller loads and the watcher doesn't get added to the watching variable.

Resources