window object not available on $scope in controller / link functions - angularjs

I placed a kendo-window in my html.
according to the docs, the window object should be available on the scope.
now, I want to bind a listener to the window's activate event from within a controller that is declared inside the window. i.e.:
markup:
<body ng-app="app">
<div kendo-window='potatoWindow'>
<div ng-controller='PotatoController'>
here
</div>
</div>
js:
var app = angular.module("app", ["ngRoute", "kendo.directives"]);
app.controller("PotatoController", function($scope){
$scope.potatoWindow.bind("activate",
function () {
console.log("potato");
});
});
... but the window object (potatoWindow) is not found on the $scope during the controller.
Qs:
why is the window object not available? am i missing something?
if there is no way to access the window object - is there a way to get the same results by other means?

I think your kendo-window markup needs to be part of the controller markup.
Also, try using the k-on-activate binding and define your function in the controller like this:
MARKUP:
<div ng-controller='PotatoController'>
<div kendo-window='potatoWindow' k-on-activate='fry()'>
here
</div>
</div>
JS:
var app = angular.module("app", ["ngRoute", "kendo.directives"]);
app.controller("PotatoController", function($scope){
$scope.fry = function(e){
console.log('fried!');
};
});

Related

angularjs dom manipulation based on button click

basically i want to change the attribute value based on the button i clicked,
these are the two buttons
<button ng-click="fn(a)"></button>
<button ng-click="fn(b)"></button>
and then i have a prebuilt directive who takes value as input,
<div directive-name="" id="abc"></div>
if i click on first button,i want the value of directive based on button clicked.
What i did earlier;
$scope.go = function(data){
if(data==a){
var b = document.querySelector( 'div' );
b.setAttribute("directive-name","value");
}
else{}
}
here the problem is that it is selecting the first div of document and setting attribute value for that.
I also tried to pass it with id like
var b = angular.element(document.querySelector('#abc'));
I also saw some custom directives to do so, but they are not working
AngularJS DOM Manipulation through Directives
If possible provide me a demo in plunkr or fiddle
and also if i want to change css property of div based on button clicked
Thanks in advance
You can do it like this.
Assign the directive-name value to a $scope.variable and then use variable as the value in HTML.
HTML - 1:
<button ng-click="go(a)"></button>
<button ng-click="go(b)"></button>
HTML - 2:
<div directive-name="{{directive}}" id="abc"></div>
JS:
$scope.go = function(data){
if(data==a){
$scope.directive = "directive-1";
}else if(data==b){
$scope.directive = "directive-2";
}
}
To assign class name to div you can define other $scope.classVar and then use that in HTML like below:
<div directive-name="{{directive}}" id="abc" ng-class="classVar"></div>
I hope this will solve your problem.
This should work, (you had some errors in your code):-
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.fn = function(data,id) {
if (data == 'a') {
var b = document.querySelector('#'+id);
b.setAttribute("directive-name", "value");
} else {
}
}
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div directive-name="" id="abc"></div>
<button ng-click="fn('a','abc')">A</button>
</div>
"Basically I want to change the attribute value based on the button I clicked."
You can do this by changing the attribute value the angular way, referencing a property of $scope or the controller instance in your template. When clicking a button, set the variable to the value you require to be passed to your directive.
Note: When you pass a value into your ngClick directive, you need to pass it as a string unless a and b are declared as properties of $scope.
Here's a basic example:
// app.js
(function() {
'use strict';
angular.module('app', []);
})();
// main.controller.js
(function() {
'use strict';
angular.module('app').controller('MainController', MainController);
MainController.$inject = ['$scope'];
function MainController($scope) {
$scope.fn = fn;
function fn(data) {
// set the value so it's accessable in the view
// therefore we can pass it into our directive
$scope.myVar = data;
}
}
})();
// directive-name.directive.js
(function() {
'use strict';
angular.module('app').directive('directiveName', directiveNameDirective);
function directiveNameDirective() {
return {
restrict: 'A',
scope: {
directiveName: '='
},
template: '<span>directiveName: {{ directiveName }}</span>'
};
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MainController as MainCtrl">
<!-- here we pass a and b as strings otherwise they get evaluated as variables -->
<button ng-click="fn('a')">Set a</button>
<button ng-click="fn('b')">Set b</button>
<hr>
<!-- here we pass myVar which is declared as a property of $scope when the fn function is called -->
<div directive-name="myVar" id="abc"></div>
<hr> myVar: {{ myVar }}
</div>
</div>

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:)

difference between init function calling from controller initialization and from html page at rendering in angular js

what is the difference between init() method calling from controller initialization time and from html page at rendering in angular js ?
html partial:
<div ng-init="init()">
---
---
</div>
controller :
angular.module('masterJs')
.controller('SignupCtrl', function ($scope, $rootScope) {
$scope.init(){
//code here
}
});
here i am calling init() method from partial. what is the difference when we call init() from controller not from the html page like:
angular.module('masterJs')
.controller('SignupCtrl', function ($scope, $rootScope) {
$scope.init(){
//code here
}
$scope.init();
});
The difference is that when you have the ng-init in the HTML, the init() function will only be called during the actual render of the page. If for any reason that content needs to be re-rendered, the init() function will be called again.
When you call the init() function on the controller, it will only run one time (when the controller is created). According to angular's documentation, this is the best practice (avoid using ng-init).
Normally you use ng-init for intitializing a ng-repeat.
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
Example:
<script>
angular.module('initExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.list = [['a', 'b'], ['c', 'd']];
}]);
</script>
<div ng-controller="ExampleController">
<div ng-repeat="innerList in list" ng-init="outerIndex = $index">
<div ng-repeat="value in innerList" ng-init="innerIndex = $index">
<span class="example-init">list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}};</span>
</div>
</div>
</div>
The way you are using the init function, is inappropriate.

Access AngularJS form in controller

Is this the correct way of doing it? The main disadvantage is that I have to do this on each form and controller.
I have one form and want to access that form by storing a variable in a controller variable and then access it in my controller.
In my view im doing this:
<form name="formName">
<div ng-init="setForm(formName);" />
</form>
And in my controller i got
$scope.setForm = function (form) {
$scope.myForm = form;
}
Now after doing this I have a controller variable which is $scope.myForm.
The form will automatically be available via $scope, no need to explicitly save it.
If you however need to log it at controller initialization you need to wait for Angular to have processed it.
HTML:
<body ng-controller="MyController">
<form name="formName">
</form>
</body>
JS:
app.controller('MyController', function($scope, $timeout) {
$scope.$evalAsync(function() {
console.log($scope.formName);
});
});
Demo: http://plnkr.co/edit/wGPKKIGjlQ6Q4GT0aAC6?p=preview

can i inherit a parent controller's variables?

Here is my code:
function ParentCtrl($scope) {
$scope.people = ["Tom", "Dick", "Harry"];
$scope.count = $scope.people.length;
}
function ChildCtrl($scope) {
$scope.parentpeople = ParentCtrl.people //this is what I would like to do ideally
}
I am nesting one angular controller inside of another one. I would like to pass variables of the first controller to the second one. Does anyone know how to do this?
NOTE
I cannot do something like
ChildCtrl.prototype = new ParentCtrl();
because I will overwrite the people property of the ChildCtrl.
By default, child scopes prototypically inherit from the parent scope (see Scope), so you already have access to the parent controller's $scope properties in the child. To prove it:
function ChildCtrl($scope) {
alert($scope.people)
}
You're getting things wrong. You are mixing controller inheritance with scope inheritance, and they are different and loosly coupled in AngularJS.
What you actually want is:
function ParentCtrl($scope) {
$scope.people = ["Tom", "Dick", "Harry"];
$scope.count = $scope.people.length;
}
function ChildCtrl($scope) {
$scope.parentpeople = $scope.$parent.people;
}
And it will work for the case:
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
</div>
</div>
But as Mark and ganaraj noticed above, this has no sense, as you can access your property of $scope.people from both
ParentCtrl and ChildCtrl.
If you want to inherit controllers from each other, you need to use prototype inheritance of controller functions themselves.
The $scope inheritance is based upon where you reference your controllers using ng-controller.
If you have something like
<div ng-controller="ParentController">
<div ng-controller="ChildController">
</div>
</div>
Then yes, the child controller will inherit the properties of the parent controller.
Note : The child controller need not be defined on the direct child in the html. It can be any child within.
Also you can get the Scope of any controller by DOM:
$needleScope = angular.element(aDomElement).scope()
Using jQuery:
$needleScope = $('#aDomElementId').scope()
Or get all Scope in the document:
$allScopes = $('.ng-scope').scope()
It might help you!!!
Scope is a special JavaScript object that connects controller with views. Scope contains model data. In controllers, model data is accessed via $scope object.
<script>
var mainApp = angular.module("mainApp", []);
mainApp.controller("shapeController", function($scope) {
$scope.message = "In shape controller";
$scope.type = "Shape";
});
</script>
Scope Inheritance
Scope is controller-specific. If we define nested controllers, then the child controller inherits the scope of its parent controller.
<script>
var mainApp = angular.module("mainApp", []);
mainApp.controller("shapeController", function($scope) {
$scope.message = "In shape controller";
$scope.type = "Shape";
});
mainApp.controller("circleController", function($scope) {
$scope.message = "In circle controller";
});
</script>
Live example as give below.
<html>
<head>
<title>Angular JS Forms</title>
</head>
<body>
<h2>AngularJS Sample Application</h2>
<div ng-app="mainApp" ng-controller="shapeController">
<p>{{message}} <br/> {{type}} </p>
<div ng-controller="circleController">
<p>{{message}} <br/> {{type}} </p>
</div>
<div ng-controller="squareController">
<p>{{message}} <br/> {{type}} </p>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script>
var mainApp = angular.module("mainApp", []);
mainApp.controller("shapeController", function($scope) {
$scope.message = "In shape controller";
$scope.type = "Shape";
});
mainApp.controller("circleController", function($scope) {
$scope.message = "In circle controller";
});
mainApp.controller("squareController", function($scope) {
$scope.message = "In square controller";
$scope.type = "Square";
});
</script>
</body>
</html>

Resources