What's the best way to decode HTML that is contained in strings passed to an Angular expression?
Example:
If I have a string returned from the server like this:
var some_val = "Hello <strong>World</strong>!"
How can I have it render the HTML rather than display it as text?
<!-- Renders to Hello <strong>World</strong>! -->
<span>{{ some_val }}</span>
Update: Here's actual use case in a repeater:
Works (unsanitized)
<div ng-repeat="category in some_list">
<p>{{ category.name }}</p>
<p ng-repeat="bullet in category.bullets">{{ bullet.desc }}</p>
</div>
Doesn't work at all
<div ng-repeat="category in some_list">
<p ng-bind-html="category.name"></p>
<p ng-repeat="bullet in category.bullets" ng-bind-html="bullet.desc"></p>
</div>
As described here, in the docs:
<span ng-bind-html="some_val"></span>
Remember that some_val must be a angular model (basically, a $scope.some_val must exist somewhere in your app)
EDIT:
I should clarify: ng-bind-html is a service in the module ngSanitize, which isn't included in the angularJS core. ng-bind-html-unsafe is part of the core ng module, but it includes the string you supply it without sanitizing it (see the example in the ngBindHtmlUnsafe docs).
If you want/need to use ngBindHtml, you need to include ngSanitize - available here
Related
The problem is the attribute ng-click="deleteItem('{|{ reservation._links.self.href }|}')
<body ng-app="ReservationList">
<div class="content" ng-controller="ReservationListController">
<div class="panel" ng-repeat="reservation in reservations">
<div class="itemId{|{reservation.id}|}">
<button class="close" ng-click="deleteItem('{|{ reservation._links.self.href }|}')">X</button>
<div class="panel-heading clearfix">
<h3 class="panel-title">{|{ reservation.firstName }|}</h3>
<h3 class="panel-title">{|{ reservation.lastName }|}</h3>
</div>
</div>
</div>
</div>
</body>
Interestingly, when i inspect the html source, the ng-click will look like this:
ng-click="deleteItem('http://localhost:8080/reservation/1')"
However when launching the ng-click function it will just give the non-compiled attribute name as the parameter:
DELETE http://localhost:8080/%7B%7C%7B%20reservation._links.self.href%20%7D%7C%7D 405 (Method Not Allowed)
The DELETE request should have http://localhost:8080/reservation/1 as the endpoint but somehow it doesnt parse the attribute when i send the DELETE request and will just annoy me with this unparsed {[{ reservation._links.self.href }]}.
Should I even use HAL links as the endpoints for CRUD operations or is it more wise to just give the id to my delete function.
Just to note DELETE requests on http://localhost:8080/reservation/1 do work when i hardcode it in.
Do not pass Angular Expression to function. Pass the variables directly without {{}}.
In your case
ng-click="deleteItem(reservation._links.self.href)"
You could try simply not using the expression syntax and pass it directly:
ng-click="deleteItem(reservation._links.self.href)"
Perhaps I'm wrong, but I'm not actually familiar with this syntax:
ng-click="{|{expression}|}"
Shouldn't be like this instead (note the lack of the pipe |)?
ng-click="{{expression}}"
Also, I think you would want to include the deleteItem call within the expression scope, no?
So, you'd end up with this:
ng-click="{{deleteItem(reservation._links.self.href)}}"
This binds the clicking of that HTML element to the invocation of the model/controller in scope that has the deleteItem function, passing into it the desired href from the expression.
Read up on expressions here: https://docs.angularjs.org/guide/expression
I may have worded this title incorrectly but I am hoping to still get some help. I am trying to use an expression that I get from an ng-repeat to include an new page using ng-include but it is not rendering. I can write in the page I want, but I want to use the expression to include multiple pages dynamically
<div ng-app="" id="container" ng-controller="pagesController">
<span ng-repeat="x in pages">
{{x.Page | uppercase}}
<b ng-if="!$last" href="#"> - </b>
<div ng-include="'{{x.HTML}}'" name="{{x.Page}}"></div>
</span>
But if I manually enter the pages like so:
<div ng-include="'generic.htm'" name="generic"></div>
It works as expected.
I am getting used to Angular.js obviously and I am not sure if this is possible or if I can do what I want really. Any help would be appreciated.
ng-include is an angular directive, and assuming x.HTML is a string, omit the {{}} and the single quotes:
ng-include="x.HTML"
I still want {{1+2}} to be evaluated as normal. But in addition to the normal interpolator, I want to create a custom one that I can program to do whatever I want.
e.g. <p>[[welcome_message]]</p> should be a shortcut for <p>{{'welcome_message' | translate}}</p>, or <p translate="welcome_message"></p>. That way, i18n apps would be much more convenient to write.
Is anything like that possible? I'm currently going through the angular.js source code, but the interpolation system looks pretty complicated(?). Any suggestions?
I created a directive that regex-find-replaces it's innerHTML. Basically, I can rewrite any text into any other text. Here's how I did it:
How do I make angular.js reevaluate / recompile inner html?
Now all I have to do is to place my directive-attribute, "autotranslate", in one of the parent elements of where I want my interpolator to work, and it rewrites it however I want it! :D
<div class="panel panel-default" autotranslate>
<div class="panel-heading">[[WELCOME]]</div>
<div class="panel-body">
[[HELLO_WORLD]
</div>
</div>
becomes
<div class="panel panel-default" autotranslate>
<div class="panel-heading"><span translate="WELCOME"></span></div>
<div class="panel-body">
<span translate="HELLO_WORLD"></span>
</div>
</div>
which does exactly what I wanted.
I don't think that's possible, but if you really want to save some characters you could create a function on your rootScope called t, then call it within your views:
<p>{{ t(welcome_message) }}</p>
I have a HTML file it iterates over a list of objects as shown and every object has a template( stored in the db) that it uses I get "List" from a web service :-
<ul>
<li ng-repeat="object in List" ng-include="object.TemplateName" > </li>
</ul>
Let object.TemplateName be "template1"
A sample template would have a specific directive with the attributes needed and few html tags as shown "template1":-
template1:-
<directive1 s-web-service-path="object.WebServicePath" >
<h1>any html content</h1>
</directive1>
my directive calls a web service to get the content to be displayed and has its own template... instead of putting directives in a template and including them cant I directly call my directive depending upon the different types of objects that i obtain in List
something like
for Object.Type="1" i call directive1 instead of template1
for Object.Type="2" i call directive2 instead of template2
ngIf or ngSwitch might be helpful here, with a few extra wrapping elements within the ngRepeat, in order to dynamically choose what to include based on Object.Type. Using ngSwitch:
<ul>
<li ng-repeat="object in List">
<div ng-switch="object.Type">
<div ng-switch-when="'1'">
<div ng-include="object.TemplateName"></div>
</div>
<div ng-switch-when="'2'">
<directive1 s-web-service-path="object.WebServicePath" >
<h1>any html content</h1>
</directive1>
</div>
</div>
</li>
</ul>
The above is not tested, so there could potentially be an error. You might also be able to cut down on some of DOM nesting level by including the ng-switch-when attributes on the directive1 / ng-include divs, but the way above makes the behaviour clear, and avoids any unexpected issues that might arise from having multiple directives work on the same element.
I'm newbie to angularjs. When I read the docs, I found it uses ng as prefix of attributes:
<body ng:controller="PhoneListCtrl">
<ul>
<li ng:repeat="phone in phones">
{{phone.name}}
<p>{{phone.snippet}}</p>
</li>
</ul>
</body>
I want to know if I can modify it as another word, such as x? Since I think x is much easier to type than ng.
Since v1.0.0rc1, these are all equivalent:
<div ng-show="isVisible">Using ng-show</div>
<div ng:show="isVisible">Using ng:show</div>
<div data-ng-show="isVisible">Using data-ng-show</div>
<div x-ng-show="isVisible">Using x-ng-show</div>
<div class="ng-show:isVisible">Using class="ng-show:isVisible"</div>
Here's working fiddle:
http://jsfiddle.net/vojtajina/Fgf3Q/
However, the main reason behind this was allowing valid html. So, you ca use x-* prefix for your custom directives, but not for Angular ones.
Check out docs for more info.