I'm new to Angular, just a question on the difference of Built-in Directives and property binding, below is some code I saw:
// ... just js expression, not relevant here
<div [ngClass]="'text-white' + ...">
Hello, World.
</div>
<div class="form-group m-2">
<label>Name:</label>
<input class="form-control" [value]=... />
</div>
so why we can't make ngClass a standard property binding just like [value] as:
<div [class]="'text-white' + ...">
why it has to be a directive?
Its possible to use [class] directly. It's even possible to combine with ngClass like in the following:
In app.component.ts
isActive = true;
componentClass = 'my-class';
In app.component.html
<div [class]="componentClass" [ngClass]="{ active: isActive }">hello</div>
If you inspect your html you will see this result:
<div _ngcontent-gej-c0="" class="my-class active">div</div>
But I wouldn't recommend it. When you will be constructing reusable components better let class attribute available for the end developer.
Literal values should be passed without brackets around the attribute.
ngclass="text-white"
If the value is variable you can pass it dynamically by wrapping the attribute in brackets:
Component.ts
myclass: string = 'text-white';
Component.html
[ngclass]="myclass"
You can also pass an object where each project is a CSS class name and the value true or false, true stating the class will be used false stating it will not.
[ngClass]="{'row': true, 'container': false}"
There is nothing stopping you building that dynamically too.
Component.ts
getClassses(): any {
return {'row': true, 'container': false}
}
Component.html
[ngClass]="getClasses()"
Related
I want to check the condition in Angular.
I want to look at two numbers that would enter Div if these two numbers were equal.
How can I check this condition?
I tried the following method and it was wrong.
<div *ngIf="'{{item1.menuID==item2.menuID}}'">
{{item1.title}}
</div>
The code you have there would evaluate to a string given you're adding single quotes around the condition, also you don't need to interpolate to access an object inside an ngIf.
If you want to evaluate if item1.menuID and item2.menuID are equal you would do
<div *ngIf="item1.menuID == item2.menuID">
{{item1.title}}
</div>
You don't require to use interpolation within [anyAttributeEnclosingSquareBrackets] or any angular attribute like *ngIf, *ngFor or some attributes like formControlName
For example:
<child-component [childAttribute]="parentComponentVariable">
<div *ngFor="let x of arrayVariable">Array Variable is present in component</div>
<input type="text" formControlName="name">
You can directly compare like below code:
<div *ngIf="item1.menuID==item2.menuID">
{{item1.title}}
</div>
Assuming that, item1 and item2 are not private variables of component and are available or initialise expectedly
<a #globalVar>
<input [(ngModel)] = "newTitle"
#newBlogTitle_l = "ngModel" >
<div *ngIf = 'newBlogTitle_l.value === "" ' >
globalVar.value = false
</div>
<button (click) = "onSave()" [disabled] = "globalVar" > Save </button>
If there is nothing in the input box, I expect the button to remain enabled.
What's the way to achieve that?
(This is just for learning purpose.)
It is not a good idea to modify values of variables in the template. It makes it hard to maintain in the long run. Variables modifications should be almost always done in the controller.
Besides, when there is a variable bound to [(ngModel)], you can use it directly to set the state of other elements. Try the following
Controller
export class AppComponent {
newTitle: string;
}
Template
<input [(ngModel)]="newTitle">
<button [disabled]="newTitle">Click me</button>
Working example: Stackblitz
I think you're going for an angular JS approach, where we can define global variables in HTML and set values. Why not just write the condition on the disabled attribute as shown below
<input [(ngModel)] = "newTitle"
#newBlogTitle_l = "ngModel" />
<div *ngIf = "newBlogTitle_l.value" >
test
</div>
<button (click) = "onSave()" [disabled] = "newBlogTitle_l.value" > Save </button>
https://stackblitz.com/edit/angular-vgxn4t?file=src/app/app.component.html
There are toggle two button (edit and submit), which button should work like toggle show/hide style on click
<button (click)="showEditBtn = false;" *ngIf="showEditBtn;"> Edit</button>
<button (click)="showEditBtn = true;" *ngIf="!showEditBtn;">Submit</button>
I need showEditBtn variable should be true in default without touching script file
Is it possible to assign a value to a variable in the template, like below example?
<div> {{ let showEditBtn = true }} </div>
stackblitz example
Figured out. It is a bit of a hack. But works perfectly
<div *ngIf="true; let showEditBtn">
<div> {{ showEditBtn }} </div>
<button (click)="showEditBtn = false" *ngIf="showEditBtn"> Edit</button>
<button (click)="showEditBtn = true" *ngIf="!showEditBtn">Submit</button>
</div>
You cannot create or set value in a variable inside interpolation {{ }}, interpolation is only used to print the output (value of variable).
Angular Interpolation is a way of data binding in Angular. And it will allow user to communicate between component and it's template (view).
String Interpolation is a one way data binding. In one-way data binding, the value of the Model is inserted into an HTML (DOM) element and there is no way to update the Model from the View.
Hope given link may help to understand well.
I highly recommend to not set or update variables in your template. All of your logic should be in the controller.
here is a simple example of how you can do it
app.component.ts:
public isEditMode: boolean;
public toggleEditMode(): void {
this.isEditMode = !this.isEditMode;
}
app.component.html
<button (click)="toggleEditMode()" *ngIf="isEditMode;"> Edit</button>
<button (click)="toggleEditMode()" *ngIf="!isEditMode;">Submit</button>
There is no way in Angular2+ to initialize the variable value in the template. You must look into the ngOnInit() function.
I have checkbox in form and I would like to use v-if directly to show/hide sections in accordance of selected checkbox values.
Is it possible or I should use watch: ?
It is possible. I would recommend adding a data model to the checkbox that toggles true or false. Then that will allow you to toggle the appearance of content using v-if.
Example:
<template>
<input type="checkbox" v-model="showContent" value="triggerString" />
<p v-if="showContent === 'triggerString'">Lorem ipsum</p>
</template>
<script>
export default {
data() {
return {
showContent: false
}
}
}
</script>
Generally speaking, we try not to use watch when we don't have to.
Update: Using the JSFiddle you included, this is how you would do it with just v-if
<template>
<input type="checkbox"
v-model="section"
name="section"
value="Epiphone"
id="epiphone">
<label for="epiphone">Epiphone</label>
<section v-if="section.includes('Epiphone')">
<h1>Epiphone</h1>
</section>
</template>
<script>
export default {
data() {
return {
section: []
}
}
}
</script>
Since there is two way binding occurring on the section array you created, there is no need for an additional div object since the only tracking that will occur will be in the section object.
The key thing to remember about v-if is that it can take actual JS expressions in it and not just data values. So you can extract out the logic from your watch method and simply plug it in there.
Hope this answers your question!
With the deprecation of bind-attr in favor of handlebar if statements for class name binding; how do I bind multiple class names to an element?
The documentation specifies the syntax for a single bound class name but not multiple:
http://guides.emberjs.com/v1.13.0/templates/binding-element-class-names/
<div class={{if isEnabled 'enabled' 'disabled'}}>
Warning!
</div>
Which results in (when isEnabled=true):
<div class="enabled"}}>
Warning!
</div>
But what if I need to bind other class names to this element? I've tried:
<div class={{if isEnabled 'enabled' 'disabled'}}{{if isNew 'new' 'old'}}>
Warning!
</div>
and (with and without the semicolon) ...
<div class={{if isEnabled 'enabled' 'disabled'; if isNew 'new' 'old'}}>
Warning!
</div>
The first is last-in wins and the second doesn't even compile.
Put quotes around the {{if}} helper:
<div class="{{if isEnabled 'enabled' 'disabled'}} {{if isNew 'new' 'old'}}">
</div>
You could also write a helper to do some of the work for you.
For reference, this is mentioned in the 1.11 release blog post.
Like many things in frameworks you can do this in multiple ways
1) You can have them both inline
<div class="{{if isTrue 'red' 'blue'}} {{if isAlsoTrue 'bold' 'underline'}}">
I have both classes
</div>
Some might argue that this on the brink of overwhelming your template with logic. I wouldn't fault you for this way, since it is only two classes, but as you expand your project you may want to consider option 2...
2) You can use use the classNameBindings of a component,
<script type="text/x-handlebars" id="components/my-cool-dealy">
<span>I love JSFiddle</span>
</script>
App.MyCoolDealyComponent = Ember.Component.extend({
classNameBindings: ['category', 'priority'],
category: function() {
//logic here
return "blue";
}.property(),
priority: function() {
//logic here
return "underline";
}.property()
});
Here is a JSFiddle of both ways