How to execute ng-change after loading data on custom directive - javascript

I wrote a custom directive in angular js that is available in plnkr,
when the directive is loaded it already calls the changed() function on MainCtrl, I need to stop changed() function until the data loads into the directive and after that, it should start to watch the changes on input which is inside the directive and BTW the changed() function should be in MainCtrl as it is in the example so is there any way to stop execution of ng-change before loading data into directive?
here is the code:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = "someName";
$scope.statusText = "unChanged";
$scope.changed = function(){
$scope.statusText = "changed";
};
});
app.directive("myDirective", function () {
return {
restrict: 'EA',
scope: {
ngModel: "=",
ngChange: "="
},
templateUrl: "template.html",
link: function ($scope, elem, attrs) {
}
}
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<my-directive ng-model="name" ng-change="changed()"></my-directive>
<p>{{statusText}}</p>
<script type="text/ng-template" id="template.html">
<input type="text" ng-model="ngModel" ng-change="ngChange" >
</script>
</body>
</html>

you have to change your directive's receive property ngModel and ngChange, it conflicts with angularhs's built in directives.
use '&' if you want to call function out of directive
refer this plunker(I just forked from your question).

Related

Angular custom directive with promise not working

I'm trying to build a directive based on Angular custom filter with promise inside. I tried defining a filter, with the same result.
The issue is that I always get {} as the value, whenever I use a promise.
The following simple example shows the issue very clearly.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
app.directive('convert', ['$q', function ($q) {
return {
template: '{{convertFunc()}}',
link: function (scope, elem, attrs) {
scope.convertFunc = function () {
var def = $q.defer();
def.resolve('test');
return def.promise.then(function (s) {
return s; // debugger doesn't stop here
}, function (e) {
return e; // debugger doesn't stop here
});
};
}
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<div data-convert></div>
</body>
</html>
Can you help finding out what am I doing wrong?
Edit
This is the plnkr I used to create the example.
Edit 2
I'm trying to show the result of the promise on a page. In my real code I'm calling a service and then building a string using values from the service.
VS debugger shows that my string is built correctly. But I cannot display it on the page. I'm under the impression, that JS/Angular fails to recognize completion of the promise. I cannot stop on the breakpoints marked above.

AngularJS Directive to include file content

I´m trying to create a directive in AngularJS for a small templating issue. In my HTML-File I have this:
<div myinclude="header.tpl.html"></div>
My directive should transform this to that:
<div>{content of file: header.tpl.html}</div>
This is how far (or not) I´ve come, but I guess, I´m missing a piece:
myApp.directive('myinclude', function () {
return {
compile: function compile( tElement, tAttributes ) {
console.log(tAttributes.myinclude); // logs filename
return {
templateURL: tAttributes.myinclude
};
}
};
});
Has anyone done something like this before, and is willing to share?
Here is the working plunker.
Try something like this:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.setValue = function(ele) {
console.log(ele)
};
});
app.directive("myInclude",function(){
return {
restrict : 'A',
link : function(scope, element, attrs){
scope.getContentUrl = attrs["myInclude"];
},
template: "content of file : {{getContentUrl}}"
}
});
HTML
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<div my-include="header.tpl.html"></div>
</body>
</html>
Its working...
app.directive('productDescription',function(){
return {
restrict:'E',
templateUrl: 'product-description.html'
};
});

Pass Javascript variable to AngularJS

I am new to AngularJS and JavaScript in general and need some help trying get a JavaScript variable into my AngularJS controller. Here is my html page:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" ng-app="test">
<head>
<meta charset="utf-8" />
<title>Test</title>
<!--Third party scripts-->
<script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript" src="js/angular-sanitize.min.js"></script>
<!--Custom scripts-->
<script type=" text/javascript" src="app/test.js"></script>
<!--Third party style sheets-->
<link type="text/css" rel="stylesheet" href="css/test.css" />
</head>
<body>
<div id="page" ng-controller="PageCtrl">
<ul>
<li ng-click="print(gBool)">Print</li>
</ul>
</div>
</body>
</html>
<script>
var gBool = false;
window.onload = function () {
gBool = true;
};
</script>
Here is the AngularJS code:
var app = angular.module('test', []);
app.controller('PageCtrl', ['$scope', function ($scope) {
$scope.print = function (boolParam) {
console.log(boolParam);
};
}]);
This just prints out 'undefined' in the console when it executes. Is this something that should work?
You need to do it in the "angular" way by using $window:
var app = angular.module('myapp', []);
app.controller('MainCtrl', ['$scope', '$window', function($scope, $window) {
$scope.memId = $window.memId;
}]);
In this line:
<li ng-click="print(gBool)">Print</li>
You are referencing a variable gBool in your scope, so its $scope.gBool
If you define in your JavaScript instead in your html, will work.
$scope.gBool = true;
Also, lookup $window and use it from your controller like this:
app.controller('PageCtrl', ['$scope', '$window', function ($scope, '$window') {
$scope.gBool = false;
$window.onload = function() {
$scope.gBool = true;
};
$scope.print = function (boolParam) {
console.log(boolParam);
};
}]);
There are two Things to focus
(i)You need to initialize the variable you can use the ng-init
(ii) Declare a function to assign the bool value initially
Here is the working Application

angular directive not rendering

i'm trying to include directives in my application, but even basic directives aren't rendering. what am i doing wrong?
angularloader.js:
var main = angular.module('ngMain', [])
.directive('myScrollable', function () {
return {
restrict: 'AE',
template: '<h3>Hello World!!</h3>'
};
});
My HTML:
<html ng-app dir="auto">
<head>
<meta name="viewport" content="width=device-width" />
<title>#Model.Title</title>
<script src="/Scripts/Libs/angular.js"></script>
<script src="/Scripts/Custom/angularloader.js"></script>
</head>
<body dir="auto">
<my-scrollable></my-scrollable>
</body>
</html>
tried also using tag or attribute ..
you should use module name in ng-app="moduleName"
like:
<html ng-app="ngMain" dir="auto">
if you assign angular module in a variable then use that variable like bellow:
var main = angular.module('ngMain', []);
main.directive('myScrollable', function () {
return {
restrict: 'AE',
template: '<h3>Hello Worlds!!</h3>'
};
});
Working PLUNKER Link
You have define your module but forget to use in html with ng-app= "you module Name". One extra thing you don't need to declare a variable main your code will work without that also.
angular
.module('myModule', [])
.directive('myDir', function{
your code
});

Element height from within an AngularJS directive

I'm trying to get the height of elements in a simple AngularJS app.
See below. What am I doing wrong? The height should be different as the lines wrap, but I get 20 reported back to me regardless of what I input in the "labels" array.
The following code can be executed here, otherwise see below.
http://js.do/code/49177
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="/">
<title>height of element in angularjs</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.8/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.8/angular-route.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
'use strict';
var app = angular.module('heightApp', ['ngRoute', 'routing']);
app.controller('heightCtrl', ['$scope', function ($scope) {
$scope.labels = [
'Hi there, I\'m a div.',
'Me too, I\'m also a div.',
'Can you see me, because I certainly can\'t see myself. I don\'t even know my own height. Isn\'t that just crazy?'
];
}]);
angular.module('routing', []).config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'height.html',
controller: 'heightCtrl'
});
}]);
angular.module('heightApp').directive('reportMyHeight', function() {
return function (scope, el, attrs) {
alert('offsetHeight = ' + el[0].offsetHeight);
}
})
</script>
</head>
<body ng-app="heightApp">
<div class="container">
<div ng-view></div>
</div>
</body>
<script type="text/ng-template" id="height.html">
<div class="row">
<div class="col-sm-4" report-my-height ng-repeat="lbl in labels">
{{ ::lbl }}
</div>
</div>
</script>
</html>
You need to wait till the next digest cycle. When you do it right away in the directive the interpolations {{ ::lbl }} inside the ng-repeat would not have expanded yet. You can place it in a $timeout turning off the applyDigest argument.
i.e, example:
angular.module('heightApp').directive('reportMyHeight', function($timeout) {
return function (scope, el, attrs) {
$timeout(init, false);
//Initialization
function init(){
console.log('offsetHeight = ' + el[0].offsetHeight, el.html());
}
}
});
Plnkr
Another way to make sure you get the height of the element is to use watch.
angular.module('heightApp').directive('reportMyHeight', function($timeout) {
return function (scope, el, attrs) {
scope.$watch('lbl', function(newval, oldval){
alert(newval + '\n\n' + 'offsetHeight = ' + el[0].offsetHeight);
});
}
})
It will only be triggered once since you use ::.

Categories

Resources