Haml interpolation with underscore template variable - backbone.js

I am trying to output an underscore template variable in my haml template but I'm not having any luck.
The HTML is not being escaped so I can't seem to figure out why the underscore variable isn't rendering.
HAML - Full Template
%script{:type => "text/template", :id => "user_list_template"}
%h4 Users
#test
%table.table.table-bordered
%thead
%tr
%th #
%th Name
%th Nickname
%th
%tbody
{{ _.each( users, function(user) { }}
%tr
%td {{= user.get('id') }}
%td {{= user.get('name') }}
%td {{= user.get('nickname') }}
%td
%a.btn{:href => "{{= user.get('nickname') }}"}
View User
{{ }); }}
The source
<tr>
<td>9</td>
<td>TacoHell</td>
<td>TacoHelll</td>
<td>
<a class="btn" href="<%= user.get('nickname') %>">
View User
</a>
</td>
</tr>
Console.log of template
<h4>Users</h4>
<div id='test'></div>
<table class='table table-bordered'>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Nickname</th>
<th></th>
</tr>
</thead>
<tbody>
{{ _.each( users, function(user) { }}
<tr>
<td>{{= user.get('id') }}</td>
<td>{{= user.get('name') }}</td>
<td>{{= user.get('nickname') }}</td>
<td>
<a class='btn' href="{{= user.get('nickname') }}">
View User
</a>
</td>
</tr>
{{ }); }}
</tbody>
</table>
I have read through previously asked question but cannot get it to work. Any ideas?
Interpolating underscore.js template with HAML
Rendering “<%%=” with HAML
Interpolate inside html attributes with Underscore.js
Edit 1
Added full template
Edit 2
console.log of template

This isn't so much a solution as it is a workaround, but one alternative would be to use a different syntax for your Underscore templates (one that doesn't involve < and >). If you look at:
http://documentcloud.github.com/underscore/#template
you'll find they provide an example of alternate Django/Mustache-style template syntax:
If ERB-style delimiters aren't your cup of tea, you can change
Underscore's template settings to use different symbols to set off
interpolated code. Define an interpolate regex to match expressions
that should be interpolated verbatim, an escape regex to match
expressions that should be inserted after being HTML escaped, and an
evaluate regex to match expressions that should be evaluated without
insertion into the resulting string. You may define or omit any
combination of the three. For example, to perform Mustache.js style
templating:
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g
};
var template = _.template("Hello {{ name }}!");
template({name : "Mustache"});
=> "Hello Mustache!"
Of course, if you were considering looking in to a more powerful templating system anyway, then it certainly wouldn't hurt to abandon _.template and use Mustache, Handlebars, or a similar templating system instead. But if you're happy with Underscore, the _.templateSettings.interpolate will let you use it without < or >.

Related

Preparation of links in the loop

There is an array of objects. I sort out of its loop.
In both series to get a link to the image?
vm.data.list- array of object.
Loop:
<tr ng-repeat="item in vm.data.list">
<td ng-bind="item.temp.day"></td>
<td ng-bind="vm.symbal"></td>
<td ng-bind-template="{{ item.humidity }} %"></td>
</tr>
As in the cycle of getting links to the image? (http://openweathermap.org/img/w/vm.data.list[0].weather[0].icon.png, http://openweathermap.org/img/w/vm.data.list[1].weather[0].icon.png and other)
I tried to do so:
<tr ng-repeat="item in vm.data.list">
<td ng-bind="item.temp.day"></td>
<td ng-bind="vm.symbal"></td>
<td ng-bind-template="{{ item.humidity }} %"></td>
<!-- <td img ng-src="http://openweathermap.org/img/w/{{item.weather[0].icon.png}}">-->
<td> <img src=http://openweathermap.org/img/w/{{item}}.weather[0].icon.png></td>
</tr>
you need to use ng-src instead of src: https://docs.angularjs.org/api/ng/directive/ngSrc. Angular will first compute the ng-src value and then construct the src for you.
Here is a basic example: jsfiddle:
<div ng-repeat="item in items">
<img ng-src="http://www.w3schools.com/{{item.f.folders[0]}}/{{item.name}}">
</div>
In your case, use :
<img ng-src="http://openweathermap.org/img/w{{item.weather[0].icon}}.png‌​">
Aside from the ng-src, be aware that:
an url beginning with something else than a protocol or a slash is relative: it will be resolved against the context of the current page. In your case, don't forget the http:// at the beginning !
all the angular expression inside the link should be inside the brackets: {{item}}.weather[0] won't work

Angular.js: How to use ng-model outside its scope

I have searched a lot for this and couldn't get an appropriate answer. I am sorry if i am asking this question again. I am new to Angular.js
my code:
<table>
<tr>
<th ng-repeat="x in setno" ng-init="parentset=$index">SET {{ x.alpha }}</th>
</tr>
<tr ng-repeat="(parentset,ques) in selected">
<td ng-repeat="x in setno">
<select ng-model="ques" ng-options="y.name for y in topics"></select>{{ques.qid}}
</td>
<td>{{$parent.ques.qid}}hi</td>
</tr>
<tr>
<td ng-repeat="x in setno">
<button ng-click="addques($index,ques.qid)" ng-model="ques.quid">add{{$parent.ques.qid}}</button>
</td>
</tr>
</table>
The ques ng-model is working fine just after the select tag but inside td tag only. How can i use it outside that particular tag.
ie, here:
<td>{{$parent.ques.qid}}hi</td>
and here:
<button ng-click="addques($index,ques.qid)" ng-model="ques.quid">add{{$parent.ques.qid}}</button>?
I have tried $parent and without it, but its not working.
Where am i going wrong?
The select tag has his own scope so you have to extend an object in the parent scope if you want to use "ques" out of the select tag.
To do so, create an object (a $scope variable) in the parent :
$scope.test;
And extends it in the select (the child scope) :
ng.model = "test.ques";
Then you can access "ques" out of the select tag.

ngIf inside ngRepeat not working inside <table> when controller defined with string

I have an ng-if inside an ng-repeat in a template, and the ng-if is not working, even if I change it to just
ng-if="false"
I can make it work by adding
ng-controller="TemplateController"
to a parent div, however when I do this, my controller cannot receive resolved arguments:
resolve: {
myVar: function() {
return "hello world";
}
}
Unknown provider: myVarProvider <- myVar
if I remove the ng-controller, and add
controller: "TemplateController"
after my resolve:, then myVar is passed successfully, however ng-if no longer works
my HTML:
<table>
<div ng-repeat=“row in rows"><tr>
<span ng-if=“row.active==1">
<td>{{row.data}}</td>
<td></td>
<td>{{ row.date | date:"MM/dd/yyyy"}}</td>
<td>
<a href=“stuff”>click me</a>
</td>
</span>
<span ng-if=“row.active > 1">
<td>{{row.otherData}}</td>
<td>{{row.str}}</td>
<td>{{ row.date | date:"MM/dd/yyyy"}}</td>
<td>
<a href=“stuff”>click me instead</a>
</td>
</span></tr>
</div>
</table>
right now, I get a whole bunch of blank cells, and both 'click me' links.
if I remove the tags, it works, but it's not in a table
moreover, not only is the ng-if not working, but any variables I reference inside {{}} are being replaced with blanks (but they also work if is removed)
jsFiddle: http://jsfiddle.net/Mh2UH/1/
The golden rule to avoid this problem is
Always have a dot in your angular bindings
ng-if="false"
Does not have a dot. Therefore the value false is being passed to the scope of the ng-if but can't be updated, since false is an immutable boolean value.
The correct way,
ng-if=status.enabled
Where status is an object.

How do I do nested interpolation in Angular JS

I have an ng-repeat that requires nested interpolation to be evaluated. Here is an example:
<div ng-repeat="i in ['1', '2', '3']">
should evaluate to {{ i }}: {{ (i>0) && ( {{ i }} ) || false }}
</div>
This throughs a $parse error. The problem I figure is that Angular can't perform nested evaluation operations, or support nested interpolation.
Is there a way around this problem?
I had a similar issue when trying to create a dynamic table component. With the following code I'm able to display any table from the database on the front end without having to define anything thanks to nested interpolation.
You just need to use square brackets for the nested interpolation.
E.G: {{row[[col.column_name]]}}
<table id="dynamicTable" class="table table-hover" cellspacing="0">
<thead>
<tr>
<th *ngFor="let col of Columns">{{col.column_name}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of Table">
<td *ngFor="let col of Columns">{{row[[col.column_name]]}}</td>
</tr>
</tbody>
</table>
Hope this helps! (Working with Angular 7)
It's giving you parse error because you can't nest {{}}..
{{ code }} basically tells angular that whatever is inside {{ }} (code in my case) is JavaScript, and js doesn't understand {{ }} syntax. This is why second {{ i }} is causing a problem.
You might also want to look at ngRepeat docs - there are some special properties, like $index, that you can use.. https://docs.angularjs.org/api/ng/directive/ngRepeat
I can't understand what's this {{ i }}: {{ (i>0) && ( {{ i }} ) || false }} statement is about , also you cannot have nested {{}} in angular js.
Are you trying to make
Working Demo
<div ng-controller="MyCtrl">
<div ng-repeat="i in ['0','1', '2', '3']">
{{ i>0 ? true: false }}
</div>
</div>
The result of what's in the {{}} will be printed - no need to nest:
<div ng-repeat="i in ['0','1', '2', '3']"> {{ i > 0 ? i : false }} </div>

How can I communicate the state of a data area's pristine state to my scope?

I have the following:
<div data-ng-controller="AdminGridContentController" >
<ng-include src="'/Content/app/admin/partials/grid-content-base.html'"></ng-include>
<ng-include src="'/Content/app/admin/partials/table-content.html'"></ng-include>
</div>
My table include looks like this:
<div ng-form name="page">
{{ page.$pristine }}
<table width="100%" cellspacing="0" class="form table" >
<tr>
<th>ID</th>
<th>Title</th>
</tr>
<tr data-ng-repeat="row in grid.data">
<td>{{ row.contentId }}</td>
<td><input type="text" ng-model="row.title" /></td>
</tr>
</table>
</div>
What I would like to do is to put a button on my grid-content-base that is enabled when the data on the table becomes dirty. I know I can check the state of that data with {{ page.$pristine }} but how can I communicate that back to the grid-content-base.html?
Note that I did try to put everything inside the "ng-form name=page" but there's a problem. On the grid-content-base I have an input select. As soon as I do a select then it makes the page show as dirty.
So I still just want to set something globally when page.$pristine becomes true or false.
There is always an option to do $rootScope.$broadcast and send a message from the table page. This can he handled in the grid page.
Something like this in table controller
$scope.$watch('page.$pristine',function(newValue) {
$rootScope.broadcast("formUpdated",{state:page.$pristine});
});
And something like this in grid controller
$scope.on("formUpdated",function(args) {
//args.state would have the state.
});
Note:$rootScope has to be injected into your controller like you inject $scope

Resources