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'
};
});
Related
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).
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.
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
I try to display some variable of my controller, but the output is just {{UserCtrl.user}} instead of the content of UserCtrl.user.
I got the following file structure:
index.html
scripts/app.js
This is the code of index.html:
<!doctype html>
<html lang="en" ng-app="birdsnest">
<head>
<meta charset="utf-8">
<title>Birdsnest</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap-theme.css">
</head>
<body>
<div ng-controller="UserController as UserCtrl">
{{UserCtrl.user}}
</div>
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
scripts/app.js:
(function() {
var app = angular.module('birdsnest', []);
app.controller('UserController', ['scope', function($scope) {
$scope.user = 'Michael';
}]);
})();
Change this line:
app.controller('UserController', ['scope', function($scope) {
To:
app.controller('UserController', ['$scope', function($scope) {
Edit:
If you're using controllerAs then I think you should rewrite your code:
app.controller('UserController', function() {
this.user = 'Michael';
});
When you're using the ControllerAs syntax in your HTML, the values that end up getting bound to the controller instance is actually on your this object.
What this means is that your code that attaches user to the scope object is incorrect; instead you should do the following:
app.controller("UserController", function() {
this.user = "Michael";
});
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 ::.