I have a Newbie AngularJS question. I was checking the tutorial and in the step 6 there's the following line of code:
<img ng-src="{{phone.imageUrl}}">
Where they explain that you must to use ng-src instead of src or else the browser will treat {{phone.imageUrl}} literally. However in the same line appears href="#/phones/{{phone.id}}" where no special tag is being used.
Why this is like that? This only applies for an <img> tag or there are another situations where you must to use ng-scr?
Both ng-src and src works just fine. The only thing to notice is when the img tag is evaluated, angular might not be loaded so the image url won't make sense to the browser. If you can guarantee that angular will be loaded before the browser evaluates img, you can use src with angular expression as the source.
Here's a jsFiddle demonstrating this.
http://jsfiddle.net/PkpL3/
HTML:
<div ng-controller="MyCtrl">
<img src="{{name}}"/>
<img ng-src="{{name}}"/>
</div>
Controller:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.name = 'https://www.google.com/images/srpr/logo5w.png';
}
Related
While using ngsanitize. It displays only html without css applied.
For example:
The above image should be the output but using ngsanitize ,it displays only the text
What could be added with ngsanitize to display elements with proper css.
<p ng-bind-html ="the text to be displayed(test video)"></p>
if i understood your question correctly, fiddle
you can use $sce.trustAsHtml(), to use inline style directly into the html string, you could do it like this, controller:
$scope.trustAsHtml = function(string) {
return $sce.trustAsHtml(string);
};
And in HTML
<div data-ng-bind-html="trustAsHtml(htmlString)"></div>
Please try with $sce. Before binding it to the scope variable that you use for ng-bind-html. An example below
<p ng-bind-html ="styledHTML"></p>
And in your controller
$scope.styledHTML = $sce.trustAsHtml('<span style="background-color: cyan;">test video</span>');
In my project called App, I have a controller, which contains a complex object that has a field referencing App/img/blue.jpg:
myApp.controller("myController",function($scope){
$scope.message = "Home Page";
$scope.Photo1 = {
name: "blue_bird",
image:"/img/blue.jpg"
};
});
However the image is not loading when I do this:
<img src="{{Photo1.image}}" />
I also tried changing the image field to img/blue.jpg and ~/img/blue.jpg, none works. When I change image to a web link, though, it works
Read the documentation here.
Using Angular markup like {{hash}} in a src attribute doesn't work
right: The browser will fetch from the URL with the literal text
{{hash}} until Angular replaces the expression inside {{hash}}. The
ngSrc directive solves this problem.
The buggy way to write it:
<img src="{{Photo1.image}}"/>
The correct way to write it:
<img ng-src="{{Photo1.image}}"/>
Found the answer. In the Projects panel on the left hand side of the window, click the Files tab, drag the file into the editing area, right between the quotation marks of the src="" attribute. The img tag then looks like this:
<img src="../img/blue.jpg" alt="" />
So the object in the controller should look like:
$scope.Photo1 = {
name: "blue_bird",
image:"../img/blue.jpg"
};
And in View:
<img ng-src="{{Photo1.image}}"/>
I'm building a mobile app with Ionic using AngularJS.
In some of the views I would like to bind HTML code having multiple links, but somehow its not working on mobile.
In the browser it works just perfectly, but on mobile the link can not be clicked.
Text I would like to bind:
"Some text http://www.test.com"
My code in HTML:
<p ng-bind-html="testDetails"></p>
$sanitize is available, ngSanitize has been added as a dependency
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-sanitize.js"></script>
var appControllers = angular.module('starter.controllers', ['ngSanitize']); // Use for all controller of application.
Any idea?
Looks I've found a solution.
Somehow simple <a> tags with href attribute does not seem to be working on mobile with ng-bind-html.
Instead, I used:
<a href="" onClick="window.open('http://www.test.com', '_system', 'location=yes')"
target="_blank">http://www.test.com</a>
This just works perfectly, but it was necessary to bypass $sanitize in ng-bind-html by explicitly trusting the dangerous value (See AngularJS documentation).
https://docs.angularjs.org/api/ngSanitize/service/$sanitize
In Controller:
$scope.testDetails = '<a href="" onClick="window.open('http://www.test.com', '_system', 'location=yes')"
target="_blank">http://www.test.com</a>'
$scope.deliberatelyTrustDangerousSnippet = function(sniptext) {
return $sce.trustAsHtml(sniptext);
};
In HTML view:
<p ng-bind-html='deliberatelyTrustDangerousSnippet(testDetails)'></p>
Also I've found a good filter to do this work, if the data is received with simple <a href="">attributes:
https://gist.github.com/rewonc/e53ad3a9d6ca704d402e
I use the verions 0.14.2 of angular-ui-bootstrap. I was unable to display line returns in the popover.
I use the popover-html directive, and a string such as
Limite inférieure<br>Limite supérieure
It gives the following error :
Lexer Error: Unexpected next character at columns 41-41 [é] in expression [<div>Approchant des limites<br>Limite supérieure: 34:12<br>Limite inférieure: -34:12</div>].
I tried wrapping my string in a $sce.trustAsHtml call, but it didn't change a thing.
Here is a plunker
http://plnkr.co/edit/3JSly1anPBUiGyqBcsD1
Works for me using $sce.trustAsHtml as below.
Note: trustAsHtml tells Angular to trust that the HTML is safe, so should only be used if you do trust the HTML, i.e. its not user-supplied.
JS:
$scope.popoverContent = $sce.trustAsHtml('Line 1<br>Line2');
HTML:
<button popover-placement="right" uib-popover-html="popoverContent" type="button" class="btn btn-default">Popover</button>
Updated Plunker
Or if your content is dynamic and you need a function:
JS:
$scope.input = 'Line 1<br/>Line 2';
var trusted = {};
$scope.getPopoverContent = function(content) {
return trusted[content] || (trusted[content] = $sce.trustAsHtml(content));
}
HTML:
<button popover-placement="right" uib-popover-html="getPopoverContent(input)" type="button" class="btn btn-default">Popover</button>
Plunker
(The reason for caching the value returned by trustAsHtml is that trustAsHtml always returns a new object so can cause an infinite $digest loop)
The accepted approach can easily lead to a cross-site scripting vulnerability in you application. You should really only use $sce.trustAsHtml if you explicitly trust the content that you want to display. The angular-bootstrap documentation also hints at that:
The user is responsible for ensuring the content is safe to put into the DOM!
An alternative and safer approach is to use uib-popover-template with a simple template in combination with ng-bind-html that automatically uses $sanitize to sanitize the HTML.
HTML
<p uib-popover-template="myPopoverTemplateUrl"
popover-trigger="mouseenter"
popover-placement="top"
popover-append-to-body="true">
Show a Popover on Hover
</p>
<script type="text/ng-template" id="myPopoverTemplate.html">
<div>
<p ng-bind-html="popoverContent"></p>
</div>
</script>
JS
$scope.myPopoverTemplateUrl = "myPopoverTemplate.html";
$scope.popoverContent = "This is HTML <b> And will be sanitized."
You also need to make sure to declare ngSanitize in your app and to include the angular-sanitize.js script. Please take a look at the updated plunker for reference.
Updated Plunker
I have some legacy jQuery code. It's a big chunk of code, so I would prefer to port it a little while later. To use it, I call $('#legacyId').legacyFunction().
Here's the deal, though.
I have an ng-if. And within that ng-if, I have the JavaScript where I call my legacy function.
<div ng-if="status=='yes'">
<div id="legacyId">
I am a legacy div!
</div>
<script type="text/javascript">
$('#legacyId').legacyFunction()
</script>
</div>
It looks like this JavaScript is being called when the page loads. Though I load angular after jQuery, it seems that angular removes the section under control of the ng-if, and therefore the jQuery function on #legacyId fails.
Any ideas? Thanks!
Edit-note: I import jQuery and the legacy code that extends jQuery at the top of my HTML document. Angular is loaded at the bottom of the document.
Edit-note 2: I have also tried <div ng-init="$('#legacyId').legacyFunction()"></div>, but I get an error, Error: [$rootScope:inprog] $apply already in progress.
Okay, managed to work this out.
In the HTML:
<div ng-if="status=='yes'">
<div legacy-directive>
I am a legacy div!
</div>
</div>
In my app code:
app.directive('legacyDirective' , function() {
return {
link: function(scope, element, attrs) {
$(element).legacyFunction(scope.$eval(attrs.legacyDirective));
}
}
});
Because of the $(element).legacyFunction(scope.$eval(attrs.legacyDirective));, it looks like I can also pass parameters to the legacyFunction; e.g. <div legacy-directive='{myParameter: true}>
Thank you for all who answered! You set me on the right track.