Using razor syntax and angular - angularjs

Is it possible to use AngularJS variable as Route Parameter in Razor Syntax like this?
<tr data-ng-repeat="job in jobs">
<td>
<a href="#Url.RouteUrl("editJob", new { id = job.JobID })">
<i class="glyphicon glyphicon-edit" style="color:#808080"></i>
</a>
</td>
</tr>
Right now I am using this.
<a href='#Url.Content("~/job/edit/"){{job.JobId}}'>

I'd say no, since Razor is rendered server side and at that time Angular variables don't exist. Meaning new { id = job.jobID } will result in { id : null }.
Your second solution is working because the angular string is concatenated right after the Razor part ends.

I recommend neither solutions because mixing multiple templates is always a bit dangerous. The way our team solves this is
pass in all razor dependencies on in a separate script block with a dynamically created constant on in the ng-init (if only used in simple cases)
only use these in your angular template
A bit like this (pseudo-code, example using ng-init)
<div ng-app="..." ng-init="config = { rootUrl: '#Url.Content("~/job/edit/")', otherValue: ''}">
...
</div>

Related

Recreating something in Vue that I did in React

I'm working on my own personal portfolio and I have my social media saved as a template to just pull from using this code in React.
{this.state.contact.map((contact, index) =>
<a className="social-icons" href={`${contact.href}`} target="_blank" rel="noopener noreferrer" key={index}>
<h3 className={`ion-social-${contact.title}`}></h3>
</a>
)}
I'm trying to create the same effect while using Vue for the ion-social-icons but I'm having a hard time figuring out how to implement it as I just receive an error talking about using v-bind:class that doesn't help much. This is what I'm currently trying.
<p class="social-media snippet ion-social-{{social.title}}" v-for="social in socials" v-bind:key="social">
{{ social.title }}
</p>
I'm relatively new to Vue also.
The error you get is:
Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead.
For example, instead of <div class="{{ val }}">, use <div :class="val">.
Off the top of my head, there are 3 ways to set an html attribute in Vue.
You want to set a string literal. Just write it as if you were writing regular HTML.
class="myClass". You cannot interpolate javascript here, which is what you're trying to do and what Vue was warning about.
You want to use a javascript variable defined in your component. Use v-bind.
v-bind:class="myClassVariable"
Same as above, where : is just a shortcut for v-bind.
:class="myClassVariable"
A working example of your class binding looks like this,
<p class="social-media snippet" :class="'ion-social-'+social.title" ...
The value inside :class="..." is simply an expression, where 'ion-social' is a string literal that's appended with the variable social.title. Once your template gets messy, which imo it is now, you should remove logic from your template and put it inside the component.
Using interpolations in HTML attributes was possible in Vue 1.0, but is no longer supported since 2.0. Here, you need to use v-bind, then add the variable with the string like you would in JS.
<p
v-for="social in socials"
v-bind:class="'social-media snippet ion-social-' + social.title"
v-bind:key="social"
>
{{ social.title }}
</p>

Self contained Angular Template is not setting variables correctly

I am trying to build a star ranking purely in an angular template file without using controllers, I have the following code which fails, I can build this using controllers (calling setRanking method ng-click) but I want to understand why the following code is not working. User should be able to click on a star and all the stars up to the selected star should be highlighted.
<div class="item" ng-init="user_rating = 0">
<i
ng-repeat="star in [1,2,3,4,5]"
ng-class="(star>user_rating) && 'ion-ios-star-outline' || 'ion-ios-star'"
ng-click="user_rating = star"></i>
<h3>Starts: {{user_rating}} </h3>
</div>
I think the issue is with the scope of the user_rating(as it is not getting updated).
As each ng-repeat creates the isolated scope, so the way you are updating user_rating is creating a local copy of user_rating associated to the local scope of each ng-repeat.
To fix it you can replace the code
ng-init="user_rating = 0"
with
ng-init="r={}; r.user_rating = 0;"
Also refer user_rating with r.user_rating wherever you are referring user_rating.
Also the correct way of using ng-class is what #Shailendra mentioned in his answer. Thanks!
You need to make changes in this code for 'ng-class' as like below-
<div class="item" ng-init="user_rating = 0">
<i
ng-repeat="star in [1,2,3,4,5]"
ng-class="star>user_rating? 'ion-ios-star-outline': 'ion-ios-star'"
ng-click="$parent.user_rating=star;"></i>
<h3>Starts: {{user_rating}} </h3>
</div>
I Hope this may help you..

Using expression from ng-repeat inside an ng-include

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"

ng-if is not working under nested ng-repeat

I am getting some server response data in two different JSON as:
userlist{id,name,type...}
and
tasklist{assign_to,tester,title,description...}
here, I need to show the task of the corresponding user.
so, I have nested the tasklist under the userlist using ng-repeat as:
<div ng-repeat="user in userList">
<table>
<tr><th>Name </th><td>{{user.name}}</td></tr>
<tr><th>Type </th><td>{{user.type}}</td></tr>
</table>
<div ng-repeat="task in taskList">
<div ng-if="task.assign_to==user.id || task.tester==user.id">
<table>
<tr><th>Title </th><td>{{task.title}}</td></tr>
<tr><th>Task Desc </th><td>{{task.description}}</td></tr>
</table>
</div>
</div>
</div>
but it's not working. As all the tasks are showing for every user.(Means ng-if is not working).
Any suggestion would be appreciated.
Angularjs code is case-sensitive. Please check variable name in scope. From the code you pasted above, the two lists should be :
userlist{id,name,type...}
and
tasklist{assign_to,tester,title,description...}
Use same in HTML. I think you are using taskList and userList (with capital L, use same name in JS and html)
All it was about the version actually. 1.0.7 doesn't support ng-if. Hence, 1.1.5 worked for me.

Conditionally change img src based on model data

I want to represent model data as different images using Angular but having some trouble finding the "right" way to do it. The Angular API docs on expressions say that conditional expressions are not allowed...
Simplifying a lot, the model data is fetched via AJAX and shows you the status of each interface on a router. Something like:
$scope.interfaces = ["UP", "DOWN", "UP", "UP", "UP", "UP", "DOWN"]
So, in Angular, we can display the state of each interface with something like:
<ul>
<li ng-repeat=interface in interfaces>{{interface}}
</ul>
BUT - Instead of the values from the model, I'd like to show a suitable image. Something following this general idea.
<ul>
<li ng-repeat=interface in interfaces>
{{if interface=="UP"}}
<img src='green-checkmark.png'>
{{else}}
<img src='big-black-X.png'>
{{/if}}
</ul>
(I think Ember supports this type of construct)
Of course, I could modify the controller to return image URLs based on the actual model data but that seems to violate the separation of model and view, no?
This SO Posting suggested using a directive to change the bg-img source. But then we are back to putting URLs in the JS not the template...
All suggestions appreciated. Thanks.
please excuse any typos
Instead of src you need ng-src.
AngularJS views support binary operators
condition && true || false
So your img tag would look like this
<img ng-src="{{interface == 'UP' && 'green-checkmark.png' || 'big-black-X.png'}}"/>
Note : the quotes (ie 'green-checkmark.png') are important here. It won't work without quotes.
plunker here (open dev tools to see the produced HTML)
Another alternative (other than binary operators suggested by #jm-) is to use ng-switch:
<span ng-switch on="interface">
<img ng-switch-when="UP" src='green-checkmark.png'>
<img ng-switch-default src='big-black-X.png'>
</span>
ng-switch will likely be better/easier if you have more than two images.
Another way ..
<img ng-src="{{!video.playing ? 'img/icons/play-rounded-button-outline.svg' : 'img/icons/pause-thin-rounded-button.svg'}}" />
<ul>
<li ng-repeat=interface in interfaces>
<img src='green-checkmark.png' ng-show="interface=='UP'" />
<img src='big-black-X.png' ng-show="interface=='DOWN'" />
</li>
</ul>
For angular 4 I have used
<img [src]="data.pic ? data.pic : 'assets/images/no-image.png' " alt="Image" title="Image">
It works for me , I hope it may use to other's also for Angular 4-5. :)

Resources