AngularJS directive variable interpreted as text before interpolated as variable - javascript

I have a fairly simple ng-repeat that iterates an AngularJS directive to display images from an array of objects, where each JSON object has a img attribute with a URL of the image. Everything works fine except in the network tools I can see that the browser is trying to load an image source URL as {{ data.img }} before being interpolated into it's actual value, it's driving me crazy trying to figure out why this is happening.
Here are the relevant pieces of my code:
index.html
<div ng-repeat="data in obj">
<feed-item></feed-item>
</div>
feedItem.html (directive)
<div class="item">
<img src="{{ data.img }}" />
</div>
Angular directive
app.directive("feedItem", function() {
return {
restrict: 'E',
templateUrl: 'assets/directives/feedItem.html',
replace: true
};
});
This results in the images rendering fine, but as mentioned the following shows up in the network tools:
All of the 2 images from the array of JSON objects are loaded fine as you can see, but I have the extra request the browser is trying to make, and the "initiator" column just says "other" which is not very helpful. Any idea why this request is being sent?

As matthewdaniel said, ng-src might solve your problem. It stops the browser from trying to load that source of the image before angular can get going, you use it just like the 'src' attribute on a normal image.

Related

View contents of Angular template on page

I have been looking for a while now and cannot seem to find the right answer to this question and I was hoping you all could help.
What I am trying to do is pass in a URL, through JSON, to my angular directive so I can display the contents/code in a template on the screen.
I am trying to create a directive cheat sheet, similar in design to that of Bootstrap's documentation page: http://getbootstrap.com/components/#btn-dropdowns
I have tried using ng-bind-html, but that only displays the URL I pass in.
My question is, can I pass in a template URL through JSON to a directive and have the contents/code of that file be displayed on the screen? Or do I need to copy all the code into the JSON file directly pass a string representation of the code to the directive?
EDIT
Here is a sample of the JSON file I am building:
{"id":"number-picker",
"title":"Number Picker",
"description":"An input box used to communicate a numeric value from the client to the server",
"code":"/js/directives/templates/number-picker.html"}
And here is a section of the directive I'm building:
<h2>{{directive.title}}</h2>
<div class="row">
<div class="col-md-2">
<span class="bold">Description:</span>
</div>
<div class="col-md-10">
<span ng-bind-html="directive.description"></span></p>
</div>
</div>
<p><span class="bold">Code:</span>
<div class="code">
<div ng-bind-html="directive.code"></div>
</div>
</p>
After a bunch of trial and error and many thanks to everyone that commented I figured out a solution.
This is the js code:
myApp.directive('directiveDetail', function($http){
return {
restrict: 'E',
templateUrl: 'js/directives/templates/directive-template.html',
link: function(scope, element, attrs) {
if (scope.directive.code) {
$http.get(scope.directive.code).then(function (response) {
scope.displaycode = response.data;
});
}
}
}
});
I needed to access the scope parameter to gain access to the URL data. I also needed to add the if statement because if I don't pass in a valid URL then the the text displayed is the entire code for the DOM.

Open link contents in django template

I have a django application and in one of the templates I have something similar to:
image
This code is called multiple times - for each memb there is an associated .svg image that can be accessed with this url. Of course at the moment, there is just a link on the word 'image' to a separate page with the .svg.
What I want is to have the .svg's loaded into the template page instead of a link out. What is the easiest/best way to do this?
I am relatively new to Python/Django but I understand the basic concepts as well as HTML/CSS, however, I have zero experience with JavaScript.
EDIT: The .svg's are not stored in the filesystem. There is a separate view (separate to the main one for the template I'm working on here) that goes a bit like this:
def svg_image(request, entry_nr):
svg_string = utils.DrawSVG.get_svg(entry_nr)
return HttpResponse(svg_string)
I then have the url, which is accessed in the HTML template code above:
url(r'^images/(?P<entry_nr>[0-9]+)/$', views.svg_image, name='svg_image')
{% load static %}
<p>
<img src="/location/images/{{memb.EntryNr}}" width="200"/>
</p>
While rendering the django template you need to pass the content_type
def myview(request):
svg_data = generate_some_svg_data()
return HttpResponse(svg_data, content_type="image/svg+xml")

Using angular-google-maps directive with <markers> loaded asynchronously not working

I'm using angular-google-maps (http://angular-google-maps.org/) to create a map in my AngularJS application. Within the <google-map> element, I have a <markers> element with the models attribute set to an array which is the result of an $http.get request. For some reason though, the markers never load.
For the sake of knowing the data exists, I setup a simple list with ng-repeat next to the map to output the id of each element in the array when the result is returned and it does indeed populate the list, so I'm not sure why the markers aren't populated when using the <markers> directive. Is it because they're being loaded from an $http.get and I need to do something different?
This is all I'm doing at the moment to get the data from the server. Trucks is a service with finder functions.
Trucks
.findAll()
.then(function(success) {
$scope.trucks = success.data;
}, function(error) {
console.debug(error);
});
My HTML looks like this.
Edit - I read the docs some more and found I need to add the coords attribute = 'self' since the longitude and latitude are part of the model itself, but the markers still don't appear
<div class="row row-fluid">
<div class="google-map col-xs-9" center="map.center" zoom="map.zoom">
<markers models="trucks" do-rebuild-all="true" do-cluster="true" coords="'self'"></markers>
</div>
<div class="col-xs-3">
<ul>
<li ng-repeat="truck in trucks">{{truck.id}}</li>
</ul>
</div>
</div>
Thanks.
I know this seems wierd and it may not solve your issue but the do-cluster attribute should actually be doCluster. Because of the way these directives are built you actually do the Camel case for these. Can you post an example of the data you are getting back? Also, I believe do-rebuild-all would also be doRebuildAll

AngularJS - Run directives explicitly

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);

Image Get Requests with AngularJS

I am storing the the source string of an image to be rendered in HTML in the AngularJS controller, however it yields a 404 before the Angular controller is initialized.
Here is the HTML:
<div ng-controller="Cont">
<img src="{{imageSource}}">
</div>
Angular controller:
var Cont = function($scope) {
$scope.imageSource = '/tests.png';
}
And the error I get (%7D%7D corresponds to the {{ in the template).
GET https://localhost:9000/%7B%7BimageSource%7D%7D 404 (Not Found)
How can I prevent this from happening? That is, only load the image when the Angular controller has been initialized?
Try replacing your src with ng-src for more info see the documentation:
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.
<div ng-controller="Cont">
<img ng-src="{{imageSource}}">
</div>
If someone is searching the solution for styling background-image then use this:
<div ng-style="{'background-image': 'url({{ image.source }})'}">...</div>

Categories

Resources