I have a a single span element in my page. I am concatenating words to a single variable in AngularJS and then referencing the variable to the span element in the page.
$scope.abc = "Downstream";
$scope.abc.concat('<b>','Upstream',</b>);
When the page is viewed, it displays Downstream<b>Upstream</b>
How to display the word Upstream alone in Bold?
according to this https://docs.angularjs.org/api/ng/directive/ngBindHtml
You need to include the ngBindHtml and $sanitize service
In your js file, it should be
angular.module('App', ['ngSanitize'])
.controller('Ctr', ['$scope', function($scope) {
$scope.abc = "Downstream";
$scope.abc2 = $scope.abc.concat('<b>','Upstream','</b>');
}]);
In your html file, it should be
<div ng-controller="Ctr">
<p ng-bind-html="abc2"></p>
</div>
Seems a duplicate to angular variable generating html.
I don't know angular, but reading that post it's easy. Just do:
$scope.abc = $scope.trustAsHtml($scope.abc);
HTML
<div data-ng-bind-html="abc "></div>
Also check your Angular version, for version 1.2 or lower you could use the ng-bind-html-unsafe binding.
<div class="post-content" ng-bind-html-unsafe="abc"></div>
This does not work anymore at Angular 1.2+ According to comment of TheSharpieOne:
"It has been replaced with Strict Contextual Escaping. See docs.angularjs.org/api/ng.$sce"
Related
I am using node and angularjs. I have a frame like page inside an ejs that is passed content to load into the includes dynamically.
<div ng-app="thisApp">
<div ng-controller='MainCtrl'>
{{ firstMessage }}
<div id='contentFromNode' ng-include='<%= pageContent %>'></div>
</div>
</div>
<script>
var thisApp = angular.module('thisApp', []);
thisApp.controller('MainCtrl', [ '$scope', function($scope) {
$scope.firstMessage = "Main Controller Working Fine";
}])
</script>
and then the passed content might be just an html page containing something like this:
<div ng-controller='NestedCtrl' id='content-type-container'>
{{ nestedMessage }}
</div>
<script>
thisApp.controller('NestedCtrl', [function(){
var nested = this;
nested.nestedMessage = "Nested Won't Work";
}])
</script>
So I have tried $scope within the NestCtrl instead of referencing this, I have tried moving the script tag above and below (ideally this get separated eventually anyway). I have tried aliasing the controllers, however my problem is the in registration of the controller itself as I get that great Error: [$controller:ctrlreg] error. The page is loading the content fine? Any ideas what I am doing wrong here?
Seems JQlite doesn't support this. You have to include jquery or lazy load the script. Refer
AngularJS: How to make angular load script inside ng-include?
I am currently trying to add links in my view. I do have links which basically contains html tags as strings.
I tried:
<p data-ng-repeat='i in links' >{$ i.link $}</p>
which basically just deploy in my view : mylink
So I did try:
<p data-ng-repeat='i in links' ><span data-ng-bind-html="i.link"></span></p>
It doesn't work though, any idea how could I achieve this ?
Thanks.
Add the $sce as a dependancy of the module
angular.module('myApp', ['$sce']);
When getting the links
angular.forEach($scope.links, function(value){
value.link = $sce.trustAsHtml(value.link);
});
Using Safe Contextual Escaping (docs.angularjs.org/api/ng/service/$sce) and using trustAs delegate you're telling Angular that this value is safe to use within that context. In this example. $sce.trustAsHtml returns an object that angular can trust is safe to as HTML.
In the first case, you'll actually want to use:
<p data-ng-repeat='i in links' >{{ i.link }}</p>
Double braces, not brace-dollar. In the second case, ng-bind-html will require that you have added "ngSanitize" to your module's dependency list.
angular.module('yourAppNameHere', ['ngSanitize'])
Edit:
If you really do want clickable links on the page, then do pretty much what #sreeramu suggested (Though I'd see if you can't find a way to add a nice description):
<p data-ng-repeat='i in links' ><a ng-href="{{i.link}}">{{i.desc}}</a></p>
(Notice that he suggested using ng-href, instead of href. He's right.)
Insert ngSanitize as a dependency to you app:
angular.module('myApp', ['ngSanitize'])
But before be ensure that you are including the script angular-sanitize.js.
Good luck!
It might be that your links have already got the a tags with it so in this case you do not need to re-add the a tags...
In this case do this...
Add this to you scripts (include acc. to your angular version)
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-
sanitize.min.js"></script>
Add this to your app.js
var app = angular.module('modulename', [ 'ngSanitize']);
And than in your view do this
If it is the div that you want the link to attach to...
<div ng-bind-html="i.link"></div>
The above would give you something as this
<div><a href='your link'></a></div>
We are working with jquery 1.9.1 and angular 1.2.13. We are using a wysiwyg editor that works great, we save the html into the database and load the html back using jquery append function and works fine. Now we are trying to append the same html into a div tag (the wysiwyg editor also uses a div) and the append function it's not working. We check in the console, and the string we are trying to append is there, also jquery grabs the element (also checked in the console log) but the append function it's not working.
PD: I apologize for my english
The html
<div data-ng-controller="PreviewCtrl">
<div class="container">
<div id="resumenPreview"></div>
</div>
</div>
The controller
angular.module('module').controller('PreviewCtrl', ['$scope', '$routeParams', '$location', '$http', 'selectedElement',
function ($scope, $routeParams, $location, $http, selectedElement) {
$scope.id = $routeParams.id;
$scope.mensaje = $scope.id;
$scope.imagen = null;
$scope.dataImagen = null;
//is not working either
$('#resumenPreview').append("hola");
$scope.pageLoad = function () {
var x = selectedElement.data.Resumen;
//This is properly displayed in the console
console.log(x);
//This too, is displayed in the console log
console.log($('#resumenPreview'));
// Why this isn't working? I'am clueless
$('#resumenPreview').append(x);
};
$scope.pageLoad();
}]);
My guess would be there are multiple divs with id="resumenPreview". But this is clearly the wrong way to handle such things in angular. There shouldn't be dom-manipulation in the controller - directives should take care of dom-related stuff. Put the html-string into the scope and let angular handle the injection into the dom:
instead of $('#resumenPreview').append(x); do $scope.resumenPreview = x;
and in the template do this:
<div class="container">
<div ng-bind-html="resumenPreview"></div>
</div>
Solve it with angularjs for the ng-bind-html to work it's necessary to include
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular-sanitize.js"></script>
and to add 'ngSanitize' as a dependency in the app module configuration. And then just do what #Johannes Reuter posted.
Thanks everybody, Greetings.
I have an AngularJS app which (reduced to relevant parts) looks like this:
<div ng-app="myModule">
<div id='container'>
<div say-hello-to name="Frank">f</div>
<div say-hello-to name="Billy">b</div>
</div>
</div>
the application works fine. Now, if after the angular bootstrapping process, I add a new dom element, which corresponds to a directive, it isn't interpreted. Note that the "Addition" is done by non-angularjs JavaScript Code.
<div say-hello-to name="Dusty">d</div>
it is just "dead" div.
JsFiddle Link: http://jsfiddle.net/Nn34X/
The question is: How can I add a new DOM Element into the application and let AngularJS know that there is a new Element to be interpreted (I could easily point angularjs exactly to all inserted elements)
Cheers, and thanks in Advance!
Retrieve the $injector service:
var $injector = angular.element(document.querySelector('#container')).injector();
Select the element:
var element = angular.element(document.querySelector('[name="Dusty"]'));
Use the $injector service to retrieve the $compile service and link the element to the scope:
$injector.invoke(function ($compile) {
var scope = element.scope();
$compile(element)(scope);
});
Demo: http://jsfiddle.net/6n7xk/
Short explanation: Call Angular JS from legacy code
I'm new to AngularJS and I'm struggling with the following issue.
I need to implement a 3 step workflow as follows:
Make a call to a web service that returns a list of strings. For example, ["apple", "banana", "orange"], etc. I intercept the response and add the angle brackets around each of these strings before I send it to the Views.
For each of the string returned by the service, I have to render
<apple />
<banana />
<orange />
Finally, get the actual AngularJS directive corresponding to each of those strings to "execute" (not sure what the right word is) and replace the elements above with the content from the templateUrl property as mentioned in each of their respective directives.
Right now, I'm doing Step 1 and Step 2 above using AngularJS. But I understand that they can be done using plain JavaScript using AJAX calls.
My problem is that the directives don't get "run" or "executed" and I have these tags displayed as plain text on the page -
<apple />
<banana />
<orange />
etc.
How do I tell Angular to replace the custom tags with the actual content from their templates?
Thanks for your help.
UPDATE: Here's what the code looks like:
<div class="content" ng-controller="mainController">
<ul class="feeds">
<li ng-repeat="fruit in fruits">
<div ng-controller="fruitSpecificController"> {{fruit}} </div> <!-- This renders <apple />, <banana />, etc. -->
</li>
</ul>
</div>
Also note that each fruit can have its own controller. In the code above, I say "fruitSpecificController", but ideally that would also be generated at runtime. For example, "appleController", "orangeController", etc. and yes, they'll be child controllers of the parent "mainController".
You can use the compile method, but there is a built in directive that will do this for you - if you are willing to load in via a URL.
ng-include
Using ng-include="'/path/to/template.html'" - the evaluated expression URL will be requested and added to the DOM as a child (compiled for you).
You can also cache the templates using $templateCache (if you want to request multiple templates at the same time or cache it for multiple includes).
That would look something like this:
$templateCache.put(/path/to/template.html, 'apple html string');
custom directive (with $compile)
Otherwise, if you want to load in and compile a string - use a directive inside of a ng-repeat.
.directive('unsafeHtmlCompile', function($compile){
return {
link: function(scope, element, attrs){
scope.$watch(attrs.unsafeHtmlCompile, function(val){
if(val !== undefined){
element.html('');
var el = angular.element(val);
element.append(html);
$compile(el)(scope);
}
});
}
}
}
Remember to remove the watcher, if your data won't change :-)
You probably just need to use the $compile service. The docs aren't super helpful but the gist is that you call $compile, passing in the DOM element (in your case the parent of your directives). That returns a function that you then execute, passing in the scope that you want to use ($rootscope is probably safe).
$compile(element)($rootScope);