I have the following html:
<li class="editor" ng-model="post.text" ng-bind-html="post.text" add-class="post.text"></li>
where post.text is a wrapped trustedValue, that looks like this:
after I unwrap it, it looks like this:
Now, I want to make a directive, that searches that trustedValue, and adds a class to the img tags. So far I have this:
function AddClassToImg($sce) {
return {
restrict: 'A',
scope: {
addClass: '='
},
link: function (scope, elem, attrs) {
var content = scope.addClass.$$unwrapTrustedValue();
$(content).find('img').addClass('test');
}
}
};
angular.module('UserProfile')
.directive('addClass', ['$sce', AddClassToImg]);
How can I get the post.text from the html, two-way-bind to it, and add to all images in post.text that class?
I am just copying your code and adding logic to compile. Their might be slight modifications you might be required to do:
function AddClassToImg($sce,$compile) {
return {
restrict: 'A',
scope: {
addClass: '='
},
link: function (scope, elem, attrs) {
var content = scope.addClass.$$unwrapTrustedValue();
var imgElement = angular.element(content.querySelector('img'));
imgElement.addClass('test');
$compile(content)(scope);
}
}
};
angular.module('UserProfile')
.directive('addClass', ['$sce', AddClassToImg]);
I solved it, for everyone wondering the same thing, here is the code:
function AddClassToImg($sce, $compile){
return {
restrict: 'A',
scope:{
addClass: '='
},
link: function (scope, elem, attrs){
var content = scope.addClass.$$unwrapTrustedValue();
var newContent = $("<div>").append($(content).find('img').addClass('col-md-12 col-xs-12').end()).html();
scope.addClass = $sce.trustAsHtml(newContent);
}
}
};
Related
Before setting the compiled html to dynamic-html div, my dynamicHtml is working correctly. As you can see, there's a onClick function in directive.
But unfortunately, after setting compiled html to div, onClick is not called anymore.
var content = $compile(res)($scope);
$('dynamic-html').html(content);
My dynamicHTML directive looks like this:
.directive('dynamicHtml', function($compile, $timeout) {
return {
restrict: 'E',
transclude: true,
link: function($scope, $element) {
$scope.datePickers = {};
$scope.onClick = function (variable, $event) {
var currentTarget = $event.currentTarget;
$scope.$parent.$parent.highlight(variable, true, currentTarget);
};
I tried to add transclude on directive as you can see. But it's not working on this case.
Can you please guide me to solve this problem?
Check it out the following code,
angular.module("myApp", [])
.directive("compiled", function($compile){
return {
restrict: "AE",
scope: {},
link: function(scope, ele, attrs){
var compiled = $compile("<div><hello-world></hello-world></div>")(scope);
ele.replaceWith(compiled);
}
}
})
.directive("helloWorld", function(){
return {
restrict: "AE",
scope: {},
transculde: true,
link: function(scope, ele, attrs){
scope.sayhello = function(){
alert("Hello World");
}
},
template: '<button ng-click="sayhello()">Say Hello</button>'
}
})
Html
<compiled></compiled>
Image Constants
angular.module('app-config', []).constant('imageConstant',
{
logoPath: 'assets/img/logo/',
faviconPath: 'assets/img/favicon/',
layoutPath: 'assets/img/layout/',
logoFileName: 'myLogo.png'
});
Directive
myApp.directive("streamingLogo", function () {
var linker = function (scope, element, attrs) {
//pass image constants here to append image url
//for ex: src = imageConstant.logoPath + imageConstant.logoFileName;
};
return {
restrict: "A",
link: linker
};
});
HTML
<img class="my-logo" id="my-logo" ng-src="{{src}}" streamingLogo/>
I have configured image url and file names in a constant file. How do
I pass it in a directive to append image path and name dynamically so
that the it gets displayed using above directive ?
The idea is to have a configuration file for image path and names so that in HTML, only ng-src="{{src}}" is passed instead of full absolute path.
Add imageConstant dependency to your directive and you are good to go, like this:
myApp.directive("streamingLogo", ['imageConstant', function(imageConstant) {
var linker = function (scope, element, attrs) {
scope.logoPath = imageConstant.logoPath;
scope.favIconPath = imageConstant.faviconPath;
scope.layoutPath = imageConstant.layoutPath;
scope.logoFileName = imageConstant.logoFileName;
};
return {
restrict: "A",
link: linker
};
}]);
Inject imageConstant to your directive and add app-config as module dependency.
myApp.directive("streamingLogo", function (imageConstant) {
var linker = function (scope, element, attrs) {
scope.src= imageConstant.logoPath;
};
return {
restrict: "A",
link: linker
};
});
then in linker function
Then in HTML
<img class="my-logo" id="my-logo" ng-src="{{src}}" streaming-logo/>
Note
Change streamingLogo to streaming-logo on HTML
You can inject your constant like any other angular provider:
myApp.directive("streamingLogo", ['imageConstant', function (imageConstant) {
var linker = function (scope, element, attrs) {
console.log(imageConstant.logoPath);
console.log(imageConstant.faviconPath);
console.log(imageConstant.layoutPath);
};
return {
restrict: "A",
link: linker
};
}]);
you have to inject constants as dependency for your directive
myApp.directive("streamingLogo", function (imageConstant) {
var linker = function (scope, element, attrs) {
};
return {
restrict: "A",
link: linker
};
});
notice that you need to inject your dependencies in other ways (check this) if you want to minifey your javascript files for production.
myApp.directive("streamingLogo", ['imageConstant',function (imageConstant) {
var linker = function (scope, element, attrs) {
};
return {
restrict: "A",
link: linker
};
}]);
You need to inject the imageConstant into the .directive function.
var myApp = angular.module('app-config', []);
myApp.directive("streamingLogo", ['imageConstant', function(imageConstant) {
return {
restrict: "A",
link: function (scope, elem, attrs) {
scope.logoPath = imageConstant.logoPath;
scope.favIconPath = imageConstant.faviconPath;
scope.layoutPath = imageConstant.layoutPath;
scope.logoFileName = imageConstant.logoFileName;
}
};
}]);
small change in Html code :
use streaming-logo instead of streamingLogo.
<img class="my-logo" id="my-logo" src="{{logoPath}}" streaming-logo/>
I want to get a value straight from an attribute directive:
<form cronos-dataset="People as p">
Form Content
</form>
In my JS I tried:
app.directive('cronosDataset',[function() {
return {
restrict: 'A',
controller: 'CronosGenericDatasetController',
scope: {
"cronos-dataset" : '#'
}
};
}])
.controller("CronosGenericDatasetController",['$scope', function($scope) {
alert($scope["cronos-dataset"]);
}]);
I want to alert "People as p" string but I get undefined. Is that right path or should I go thorough a different approach?
You are supposed to have camelCase in the scope declaration
app.directive('cronosDataset',[function() {
return {
restrict: 'A',
controller: 'CronosGenericDatasetController',
scope: {
cronosDataset : '#'
}
};
}])
Here is a demo to see different variations
http://plnkr.co/edit/G6BiGgs4pzNqLW2sSMt7?p=preview
Make a link function instead:
app.directive('cronosDataset',[function() {
return {
scope: {},
restrict: 'A',
link: function (scope, elem, attrs) {
alert(attrs.cronosDataset);
}
I need the HTML in newValue to work but it seems to just spit out escaped charaters
.directive('ngLookup', function () {
return {
restrict: 'A',
scope : {
text : '='
},
template: '{{newValue}}',
link: function (scope, elem, attrs) {
scope.newValue = scope.text.replace(/test/g,'test');
}
}
})
My solution using the answer below:
.directive('ngLookup', function ($compile) {
return {
restrict: 'EA',
scope : {
text : '='
},
link: function (scope, elem, attrs) {
var txt = '<span>'+scope.text.replace(/test/g,'test')+"</span>";
var newElement = $compile(txt)(scope);
elem.replaceWith(newElement);
}
}
})
You will have to compile the HTML yourself with the $compile-Service.
Do something like:
.directive('ngLookup', function ($compile) {
return {
restrict: 'A',
scope : {
text : '='
},
link: function (scope, elem, attrs) {
var newElement = $compile('test')(scope);
elem.replaceWith(newElement);
}
}
})
How do I replace an Angular attribute that already has a value in it? For example:
angular.module('app', [])
.directive('edit', function(){
return {
template: '<a ng-href="{{data}}">Link Text</a>',
replace: true,
link: function(scope, elm, attr){
scope.data = 'http://www.example.com';
}
};
});
HTML:
<a edit ng-href="test"></a>
That just appends the link url to the "test" href. I tried using
elm.attr('ng-href', '{{data}}');
and many variations on that idea, but it didn't work.
You can use compile function in directive, and redeclare this attribute in it:
.directive('edit', ['$timeout', function($timeout) {
return {
template: '<a ng-href="{{data}}">Link Text</a>',
replace: true,
restrict:'A',
compile:function(elm, attr){
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
iAttrs.ngHref = "{{data}}";
},
post: function postLink(scope, iElement, iAttrs, controller) {
scope.data = 'http://www.example.com';
}
}
}
}
}])
http://plnkr.co/edit/lBA9xR1VbWHqHbc5KG7w?p=preview