How to avoid rendering directive element - javascript

Is it possible to hide my directive html element?
I mean if I have this directive:
app.js
angular.module("myApp", [])
.directive("myDirective", function() {
return {
restrict: "E",
template: "<div><p>Some text...</p></div>"
}
);
Only render the content of the template.
<div>
<p>Some text...</p>
</div>
Not the directives element:
<my-directive>
<div>
<p>Some text...</p>
</div>
</my-directive>

yes just put the replace: true in the directive. it will remove the element
angular.module("myApp", [])
.directive("myDirective", function() {
return {
restrict: "E",
template: "<div><p>Some text...</p></div>",
replace: true
}
);
Demo
angular.module("app",[])
.controller("ctrl",function($scope){
}).directive("myDirective", function() {
return {
restrict: "E",
template: "<div><p>Some text...</p></div>",
replace : true
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<my-directive>
</my-directive>
</div>

Note that replace: true is marked as deprecated (I use it myself nonetheless from time to time)
See: Explain replace=true in Angular Directives (Deprecated)

Related

How to call link function method from html ng-click?

I have the following code in my directive:
testModule.directive('TestOne',function(){
return{
replace: true,
controller: 'TestCtrl',
link: function(scope, element, attrs){
element.on('click', function(e) {
//my own code is there
});
}
}
}
I wanted to call the above click function on ng-click with the below event in html(ng-click="mytest()"). How can I call or write exactly so that I can execute my function requirements in the above directive's element click function as per my requirements.
html:
<div test-one ng-repeat="items in testjson">
<div class="title">{{items.name}}</div>
<div class="context-menu">
<ul>
<li ng-click="mytest()">TestFunction</li>
</ul>
</div>
</div>
Thanks in advance.
First make the first letter of the directive simple
directive('TestOne',function(){
to
directive('testOne',function(){
Then create a scope function for ng-click inside the link function
.directive('testOne',function(){
return{
restrict : 'A',
replace: true,
link: function(scope, element, attrs){
scope.mytest = function() {
console.log("working")
}
}
}
})
Demo
angular.module("app",[])
.controller("ctrl",function($scope){
$scope.testjson = [{"name":"sss"},{"name":"ssss"}]
}).directive('testOne',function(){
return{
restrict : 'A',
replace: true,
link: function(scope, element, attrs){
scope.mytest = function() {
console.log("working")
}
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div test-one ng-repeat="items in testjson">
<div class="title">{{items.name}}</div>
<div class="context-menu">
<ul>
<li ng-click="mytest()">TestFunction</li>
</ul>
</div>
</div>
</div>

How to add an inner wrapper to an element in angular?

I want an angular diretive to add an inner wrapper to a DOM element. Unfortunately it's not wrapping but replacing the inner part of the element. (see plunker)
So I have this html snippet:
<body ng-app="plunker">
<div class="outer" wrapp-my-content>
<label>Name: </label>
<input type="text" ng-model="name" />
<p>Hello {{name}}</p>
</div>
</body>
The directive should change this into
<body ng-app="plunker">
<div class="outer" wrapp-my-content>
<div class="inner-wrapper">
<label>Name: </label>
<input type="text" ng-model="name" />
<p>Hello {{name}}</p>
</div>
</div>
</body>
But what I get is
<body ng-app="plunker">
<div class="outer" wrapp-my-content>
<div class="inner-wrapper">
</div>
</div>
</body>
Directive Code:
var app = angular.module('plunker', []);
app.directive('wrappMyContent', function() {
return {
restrict: 'A',
transclude: true,
replace: true,
link: function(scope, element) {
var innerWrapper = angular.element('<div class="inner-wrapper" ng-transclude></div>');
element.prepend(innerWrapper);
}
}
});
How can I fix that?
You've mixed up ng-transclude and custom transclude by link:
1. Use template of directive (demo):
var app = angular.module('plunker', []);
//Recommended angular-way
app.directive('wrappMyContent', function() {
return {
restrict: 'A',
transclude: true,
template:'<div class="inner-wrapper" ng-transclude></div>',
link: function(scope, element) {
}
}
});
2. Do transclude by custom link (demo) :
var app = angular.module('plunker', []);
//Equals transclude by your self
app.directive('wrappMyContent', function($compile) {
return {
restrict: 'A',
scope:true,
link: function(scope, element) {
var innerContent = element.html();
var innerWrapper = angular.element('<div class="inner-wrapper"></div>').append(innerContent);
//Do compile work here.
$compile(innerWrapper)(scope.$parent)
element.empty().append(innerWrapper);
}
}
});
Use a template for your '<div class="inner-wrapper" ng-transclude>' part instead of just making an element and prepending it... the ng-transclude directive won't be processed unless it's compiled which the template will be.

Directive: append templateUrl as a sibling element

I want to append, as a sibling element, the contents of a template file using an attribute directive on an Input Text field.
I've tried this, but the contents of the template are being wrapped inside of <input></input> tags and this is not the desired behavior. I need to put the content of template file as a sibling of the input text. Anyway, angular code is executed without error on the template file.
I tried with Transclude but without success.
HTML
main page
<input type="text" ng-model="myModel" name="inputName" ng-my-directive>
template.html
<div>
<div ng-repeat="row in rows">
<button ng-repeat="button in row">{{button}}</button>
</div>
</div>
JS
.directive('ngMyDirective', function ($compile) {
return {
require: '?ngModel',
restrict: 'A',
transclude:true,
templateUrl: 'template.html',
controller: ['$scope', function ($scope) {
...
},
link: function (scope, element, attrs, ngModelCtrl, transclude) {
...
element.append(transclude());
}
Currently, I have this (wrong) result:
<input type="text">
<div>
...
</div>
</input>
And I need this result:
<input type="text">
<div>...</div>
<div>...</div>
...
Thanks in advance for your effort!
You could try using element.after() with the template contents:
angular.module('myApp', [])
.directive ('ngMyDirective', function() {
return {
restrict: 'A',
link: function(scope, element) {
element.after('<h3>sibling content</h3>');
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<input type="text" ng-model="myModel" name="inputName" ng-my-directive>
</div>
The problem with this approach is to append a "template.html" file. In this case, you could fetch the HTML contents in an ajax request. Example:
app.directive('ngMyDirective', function($http, $compile) {
return {
restrict: 'A',
link: function(scope, element){
$http.get('template.html')
.then(function(response){
element.after($compile(response.data)(scope));
});
}
});

how to dynamically append directive to div in angularjs

var myApp = angular.module('myApp', []);
myApp.controller('someController', function($scope) {
$scope.click = function(){
alert("asd");
};
});
myApp.directive('testInput',function(){
return {
restrict: 'E',
replace: false,
transclude: false,
template: '<div>asdasdasdasd</div>',
controller: function($scope) {
}
};
});
HTML:
<div ng-app = "myApp" ng-controller = "someController">
<div class = "clickme" ng-click ="click()">
click me
</div>
<div id="container">
</div>
</div>
Without using Jquery is there any good Angular way to append directive(testInput) to #container ?
see below jsfiddle link
http://jsfiddle.net/4L6qbpoy/1/
More Angular approach is to use ngIf/ngShow with some flag in controller:
var myApp = angular.module('myApp', []);
myApp.controller('someController', function($scope) {
$scope.click = function() {
$scope.test = true;
};
});
myApp.directive('testInput', function() {
return {
restrict: 'E',
replace: false,
transclude: false,
template: '<div>asdasdasdasd</div>',
controller: function($scope) {}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="someController">
<div class="clickme" ng-click="click()">click me</div>
<div id="container">
<test-input ng-if="test"></test-input>
</div>
</div>

Array of elements to control view (AngularJS)

What I'm trying to do:
Is there any way to use an array of elements to populate a div with children in AngularJS?
I want to be able to have an array of custom elements, and as I update the array, it updates the view. The directives for the custom elements need to $scope.$digest() the elements each time I make an update.
Pseudo Code:
html
<div id="parent" ng-controller="parentCtrl" ng-bind-html="arrOfElems"></div>
Javascript
app.controller('levelCtrl', ['$scope', '$compile', '$element', function(scp, cmpl, elem) {
scp.arrOfElems = ['<ell></ell>', '<r-ell></r-ell>', '<sqr></sqr>'];
}]);
app.directive('ell', function() {
return {
restrict: 'E',
template: <div class="block"></div>
};
});
app.directive('rEll', function() {
return {
restrict: 'E',
template: <div class="block"></div>
};
});
app.directive('sqr', function() {
return {
restrict: 'E',
template: '<div class="block"></div>'
};
});
Ideally, the resulting html would be:
<div id="parent" ng-controller="parentCtrl" ng-bind-html="arrOfElems">
<ell>
<div class="block"></div>
</ell>
<r-ell>
<div class="block"></div>
</r-ell>
<sqr>
<div class="block"></div>
</sqr>
</div>
Create a simple loading directive that compiles them and inserts them
<div id="parent" ng-controller="parentCtrl" my-loader="arrOfElems"></div>
Untested but should work:
app.directive('myLoader',function($compile){
return function(scope, elem, attrs){
var arrOfElems=scope[attrs.myLoader];
angular.forEach( arrOfElems, function(newEl){
elem.append( $compile(newEl)(scope) );
});
}
});
DEMO

Categories