Using class with angular vs ng-class while using a mixed expression - javascript

I have a div that I want to give a dynamic class with AngularJS.
The div is withing an ng-repeat statement where lang.prefix is first en then sv
Using the following code works and sets the class to i-flag-en than i-flag-sv, but is it correct?
<div class="float-left flag i-flag-{{lang.prefix}}"></div>
I know there exist a ng-class directive which can be used to dynamically set the class of an element with AngularJS.
I think I read somewhere in a book, that the normal class directive not should be used to set the class property dynamically with AngularJS because of the way Angular manipulates the dom.
However, the following code does not work:
<div class="float-left flag" ng-class="i-flag-{{lang.prefix}}"></div>
and I rather want to set the class in this way instead of creating another scope variable.
Is it bad practice to use the class attribute with AngularJS to dynamically set the class? Does it work all the time even if it would be bad practice?

The book you have mentioned may have talked about the problems of using ng-class and class {{}} interpolations together wherein updates in the interpolation removes the ng-class classes, this problem has already been resolved, reference. Thus, using interpolation within class attributes is totally fine, and does not break good practice because both has its own quirks.
Your usage of ng-class however is incorrect, you have to concatenate the literal string value with your scope string variable:
<div class="float-left flag" ng-class="'i-flag-' + lang.prefix"></div>
but I think it is much preferable to use your first example instead:
<div class="float-left flag i-flag-{{lang.prefix}}"></div>

Related

Is there a difference between [class]="'success'" and class="success" in Angular?

In Angular is there a difference between [class]="'success'" and class="success"?
So for example:
<li class="success">...</li>
or
<li [class]="'success'">...</li>
IIUC the latter will cause the replacement of the former if both are used at the same time, so I'm trying to better understand why we would not just use the first one?
The first one (class) is just a html class attribute.
The latter ([class]) is actually an angular binding, meaning that whatever is in it will be parsed just like any other angular binding (you can put angular/javascript expressions in it).
You are fine to use class if the classes doesn't need to change. Use [class] if you plan to change them. You can even mix them up, like:
<li class="success" [class.active]="true">...</li>

VueJS v-bind not working with kebab-case

I am working on a task list with Vue.JS (like everyone) and I've managed to add a task, show the tasks and even to delete the tasks. After that I was working on checking tasks and give them a class for success.
So I thought, if I have a data like class set to false, and use this line of code:
<div v-for="(task, index) in tasks" class="panel panel-default" :class="{panel-success: task.class}" :key="task">
I could set the class to true with a click event and give the particular class of panel-success (from bootstrap).
When I was doing that, I came up to the following problem:
avoid using JavaScript keyword as property name: "class" in expression :class="{panel-success: task.class}"
The problem was, the kebab case syntax of panel-success. When I changed the name to panelsuccess it was working. Why is kebab case not working?
The value for :class is a Javascript object, and in Javascript objects a kebab-case identifier is not valid, that's why you're having that error. For it to work, simply wrap your kebab-case identifier around single quotes:
:class="{'panel-success': task.class}"

Angular 2 ng-if fails

Trying to apply css styles dynamically for the element which has ng-if condition.
Works fine, if the condition is true. Is there any way that I can modify the element even if the condition fails. I know I can find the element (by getElementsByClassName) and modify but is there any other better solution other than this?
ex:
<span *ngIf="orderBy=='asc'" [ngStyle]="{'height': value+ '%'}"></span>
<span *ngIf="orderBy=='desc'" [ngStyle]="{'height': value+ '%'}"></span>
You can use ngClass for that. Add class based on the conditional value.
[ngClass]="{orderBy=='asc'? 'someclass': 'otherclass'}"
You can write seperate styles for each of the class.
You can use ng-class to achieve this
ng-class="{'classname':orderBy==='asc',
'classname':orderBy==='desc'}"

Is it bad form to use html class attribute as a variable

I am wondering if the html class attribute should only be used for styling. Is there any drawback to using the class attribute as a variable. The W3 spec http://www.w3.org/TR/html5/dom.html#classes does not specify one way or another but, all examples and training point in the direction of styling only for multiple objects.
In my case I want to use the class attribute as variable that matches the key value in a object array. For example in my Javascript code I have an object that has a number of key/value pairs. On my web app I have a number of save buttons. When a save button is clicked I grab the parents class attribute value and use it as the key for the object to know which value to change. The class attribute on the parent has not other value than to let me know which key value pair to change in my object
While I'm sure it's possible to use classes that way, it's certainly not their intended purpose. html has data attributes that provide the functionality you want, for example
<button data-key="some value" name="" id="">click me</button>
You can then get that value (onClick if you like) and use it as a key for your object/data structure. Theres a good overview here
While it is not bad, it neither is best practice.
You can, instead of using the class attribute, define explicit data attributes. Using the class attribute would mean that you could not use several classes (because that would be a weird key to search for in an object, right?).
For instance:
<div class="any classes you like" data-mykey="searchforthiskey">
<button></button>
</div>
In jQuery:
$('button').click(function() {
var key = $(this).closest('div').attr('data-mykey');
});
From a functional perspective, there's no reason to NOT use the class attribute to store information about that element. You can access a class attribute as easily as you can a data attribute.
From a standards perspective, it is probably better to use a data attribute. Why? Well, if you are the only person working on your front-end, no big deal. If you are one of many on a team of front-end developers, who works specifically on the javascript side of things, you may run into a conflict with another front-end developer who works on the HTML/CSS side of things. They may remove a class from the element, not realizing that its also being used as your javascript hook into that element. In that case, you're better off creating your own data attribute, which then makes it clear that this attribute is probably data related and won't be molested by someone just trying to fix the styling of that element.

Angularjs: variables in html attributes and within <style> markup

I would like to know how to put an angularjs model as the value for an html attribute. such as:
<div ng-controller="deviceWidth"
width={{width}}>
</div>
also, how would I do this within <style> markup? Where would I put ng-controller?
div {
width:{{width}}
}
Thanks,
Ben
You'd better do create own custom directive instead of the "static" width, and interpret the interpolation with $observe function.
Post pretty similar, involving some solutions:
String Interpolation Won't Work when Setting Attribute Values on a Custom Directive
Concerning the markup, you'd better play with ng-class, whose value comes from your controller logic.

Categories