(function () {
'use strict';
angular.module('product')
.directive('sampledirective', ['$document') {
return {
restrict: 'E',
replace: true,
scope: {
data: '=',
btnClick: '&'
},
link: function (scope, element, attr) {
var compiled = $compile(template)(scope);
angular.element(element).replaceWith(compiled);
element = compiled;
};
};
}]);
})();
I have a directive which replaces the elements inside it.
I have a weird issue which replaces the elements mulitple time in the directive .
Duplicates the elements in the below bolded line which should not happen.
angular.element(element).replaceWith(compiled);
Please let me know why the elemenst are duplicated and let me know how to avoid it .
sample
Actual
cool cool
expected
cool
The following directive only replaces the content once in my case. If this dosn't solve your problem maybe you could provide a small working example or so. Also note that if you use an isolated scope for your directive you should provide a template, as stated in this post.
angular.module('product').directive("sampledirective", function ($compile) {
return {
template: '',
restrict: 'E',
scope: {
data: "=data",
btnClick: '&'
},
link: function (scope, element, attrs) {
var template = "<div>foo</div>"
var compiled = $compile(template)(scope);
element.replaceWith(compiled);
}
}
});
Related
I have a Directive:
var ActorDisplayDirective = function() {
return {
replace : false,
restrict : 'AE',
scope : {
actor : "="
},
templateUrl: staticContext + '/angular-app/templates/actor-display-template.html',
link : function(scope, elem, attrs) {
},
}
};
This works fine in some places, but not others. Here is my code to show it where it is not working:
<p>CAP: {{can_approve_for}}</p>
<p>
Actor display template:
<span actor-display actor='can_approve_for'></span>
After template
</p>
The CAP: ... displays the data, the directive's actor value is null. Why? My controller does:
dataFactory.getCanApproveFor().then(function(data) {
$scope.can_approve_for = data;
});
So, I am able to see the value on the page, but the directive does not show it. I'm assuming it's a timing/refresh thing, but this directive works elsewhere in ng-repeat, because the ng-repeat evaluates after hte object is already set, I guess. How do I do it in this case?
You are not actually declaring ActorDisplayDirective as a directive. Its just a plain function that returns an object that sort of looks like a directive.
You have to tell angular that it is a directive like so:
angular.module('someModule', [])
.directive('actorDisplay', function () {
return {
replace: false,
restrict: 'AE',
scope: {
actor: "="
},
templateUrl: staticContext + '/angular-app/templates/actor-display-template.html',
link: function (scope, elem, attrs) {
},
}
})
I'm trying to display the elements of an array using ng-repeat and a directive. The directive part is important to the solution. However the element of the array is not getting bound and displays an empty value.
The fiddle can be found at http://jsfiddle.net/qrdk9sp5/
HTML
<div ng-app="app" ng-controller="testCtrl">
{{chat.words}}
<test ng-repeat="word in chat.words"></test>
</div>
JS
var app = angular.module('app', []);
app.controller("testCtrl", function($scope) {
$scope.chat = {
words: [
'Anencephalous', 'Borborygm', 'Collywobbles'
]
};
});
app.directive('test', function() {
return {
restrict: 'EA',
scope: {
word: '='
},
template: "<li>{{word}}</li>",
replace: true,
link: function(scope, elm, attrs) {}
}
});
OUTPUT
["Anencephalous","Borborygm","Collywobbles"]
•
•
•
Expected output
["Anencephalous","Borborygm","Collywobbles"]
•Anencephalous
•Borborygm
•Collywobbles
Appreciate your help
You didn't bind word.
You have used isolate scope. If you don't bind with it's scope property,it won't work.
scope: {
word: '='
},
Try like this
<test word="word" ng-repeat="word in chat.words"></test>
DEMO
var app = angular.module('dr', []);
app.controller("testCtrl", function($scope) {
$scope.chat= {words: [
'Anencephalous', 'Borborygm', 'Collywobbles'
]};
});
app.directive('test', function() {
return {
restrict: 'EA',
scope: {
word: '='
},
priority: 1001,
template: "<li>{{word}}</li>",
replace: true,
link: function(scope, elm, attrs) {
}
}
});
Your directive needs to run before ng-repeat by using a higher priority, so when ng-repeat clones the element it is able to pick your modifications.
The section "Reasons behind the compile/link separation" from the Directives user guide have an explanation on how ng-repeat works.
The current ng-repeat priority is 1000, so anything higher than this should do it.
I'm having trouble with an angular directive. It doesn't seem to run the link function.
I feel like it's something obvious, but I just can't figure it out.
The directive is required as seen from below
angular.module('test').requires // ["injectedModule"]
Code below. Fiddle.
Any help would be amazing.
angular
.module('test', ['injectedModule'])
.controller('tester', [
function() {
this.test = function(data) {
alert(data);
}
}
]);
angular
.module('injectedModule', [])
.directive('testing', [
function() {
return {
restrict: 'E',
scope: true,
link: function(scope, element, attrs) {
alert(scope, element, attrs);
}
};
}
]);
<div ng-app="test">
<div ng-controller="tester as t">
<video id="test" ng-src="https://scontent.cdninstagram.com/hphotos-xfa1/t50.2886-16/11726387_1613973172221601_1804343601_n.mp4" testing="t.test(el)" />
</div>
</div>
Looks to me like
restrict: 'E',
should be
restrict: 'A',
Your directive isn't being called at all as it is.
I think the error is in the restriction you are giving to your directive.
You are restricting your directive to match only element (in other words tag). You should restrict to match attribute 'A'. Here's angular official documentation https://docs.angularjs.org/guide/directive
and here's your fiddle working
Code sample:
angular
.module('injectedModule', [])
.directive('testing', [
function() {
return {
restrict: 'A',
scope: true,
link: function(scope, element, attrs) {
alert(scope, element, attrs);
}
};
}
]);
I am trying to implement dynamically configurable fields. I will get validation rules ng-required, ng-hidden, ng-disabled etc attributes as json from the server and set them dynamically through a directive.
I have the following directive code. It displays select values doubled JsBin link is http://jsbin.com/jiququtibo/1/edit
var app = angular.module('myapp', []);
app.directive('inputConfig', function( $compile) {
return {
require: 'ngModel',
restrict: 'A',
scope: '=',
compile: function(tElem, tAttrs){
console.log("compile 2");
tElem.removeAttr('data-input-config');
tElem.removeAttr('input-config');
tElem.attr('ng-required',true);
return {
pre: function (scope, iElement, iAttrs){
console.log('pre');
},
post: function(scope, iElement, iAttrs){
console.log("post");
$compile(tElem)(scope);
}
}
}
};
});
How can I solve this issue? I should be able to add directive dynamically.
To solve your problem you need to remove the following line from your post function:
$compile(tElem)(scope);
It's not clear to me why you are compiling here so I'm not sure if there will be any unintended side effects from this.
I found a solution following code is working.You should first clone, remove directive, prepare dom and compile
app.directive('inputConfig', function( $compile) {
return {
require: '?ngModel',
restrict: 'A',
compile:function (t, tAttrs, transclude){
var tElement = t.clone() ;
tElement.removeAttr('input-config');
tElement.attr('ng-required',true);
t.attr('ng-required',true);
return function(scope){
// first prepare dom
t.replaceWith(tElement);
// than compile
$compile(tElement)(scope);
};
}
}
});
I have a list of person objects. I have a directive for displaying some read only data about the person and nested inside it a directive that acts as the toolbar for actions on the person (delete, friend etc). When you click on the first directive a second nested directive shows up to for editing the person.
In the simple example in plnker this works fine, but in actual life this gets really flimsy with fields not updating, or updating infinitely (editor has quite a few ngRepeats making things even weirder) etc.
It seems awkward that I have 3 isolated scopes and pass the the same object to all three, but on the other hand I need a lot of properties/methods of that object in all 3 directives so it makes sense to pass the whole object. Is there a better way of doing this?
app.directive('personCard', [function () {
var directive = {
link: link,
restrict: 'A',
templateUrl: 'personcard.tpl.html',
scope: {
person: '='
}
};
return directive;
function link(scope, element, attrs) {
scope.isOpen = false;
scope.person.close = function(){
scope.isOpen = false;
}
scope.person.edit = function (){
scope.isOpen = true;
}
}
}]);
app.directive('personToolbar', [
function () {
var directive = {
link: link,
restrict: 'A',
templateUrl: 'personcardtoolbar.tpl.html',
scope: {
person: '=',
close: '&',
edit: '&'
}
};
return directive;
function link(scope, element, attrs) {
}
}]);
app.directive('personEditor', [
function () {
var directive = {
link: link,
restrict: 'A',
templateUrl: 'personeditor.tpl.html',
scope: {
person: '='
}
};
return directive;
function link(scope, element, attrs) {
}
}]);