Angular 2 - same component with different text - data-binding

I would like to use same component many times, but with different text. How can I do that?
My code:
jumbotron.component.html:
<div class="jumbotron text-center">
<h1 >{{jumbotronText}}</h1>
</div>
app.component.ts
#Component({
selector: 'my-app',
template: `
<navbar></navbar>
<jumbotron ></jumbotron>
<jumbotron ></jumbotron>
<jumbotron ></jumbotron>
`
,
directives: [NavbarComponent, JumbotronComponent]})
export class AppComponent { }
I tried do it like this:
<jumbotron [jumbotronText]="My text to display"></jumbotron>
And this:
<jumbotron jumbotronText="My text to display"></jumbotron>
But only got errors. I think that should be easy, but I cant find idea how to solve that.

First, you have to mark the jumbotronText with the Input() annotation in the Jumbotron component:
#Component({
selector: 'jumbotron',
template: `
<div class="jumbotron text-center">
<h1 >{{jumbotronText}}</h1>
</div>`
})
export class JumbotronComponent {
//here is important line
#Input() jumbotronText:string = "";
constructor() { }
}
Then, you can pass data in from the caller. If it is static text you can do this:
template: `
<navbar></navbar>
<jumbotron jumbotronText="One" ></jumbotron>
<jumbotron jumbotronText="Two" ></jumbotron>
<jumbotron jumbotronText="Three" ></jumbotron>`
And if it is calculated text you do:
template: `
<navbar></navbar>
<jumbotron [jumbotronText]="variableFromCaller1" ></jumbotron>
<jumbotron [jumbotronText]="variableFromCaller2" ></jumbotron>
<jumbotron [jumbotronText]="variableFromCaller3" ></jumbotron>`
That is, if you have variables in the app component which store the strings (or methods, or are somehow otherwise calcualted) you use square brackets to indicate one-way binding. Otherwise, if you have static text you just assign the Input() value the same as any other HTML tag property.
See this Plunker: https://embed.plnkr.co/ve31cnEDidcLeEF7dfVj/

You will either need to use #Input or ng-content. By using the {{ }} syntax you are telling Angular to look for a variable named jumbotronText in AppComponent, but that doesn't exist.
Using #Input()
jumbotron.component.html
<div class="jumbotron text-center">
<h1>{{ jumbotronText }}</h1>
</div>
jumbotron.component.ts
#Component({
// ...
}) export class JumbotronComponent {
#Input() jumbotronText: string;
// ...
}
app.component.ts
#Component({
selector: 'my-app',
template: `
<navbar></navbar>
<jumbotron [jumbotronText]="My text to display"></jumbotron>
`
,
directives: [NavbarComponent, JumbotronComponent]})
export class AppComponent { }
Using ng-content
jumbotron.component.html
<div class="jumbotron text-center">
<h1><ng-content></ng-content></h1>
</div>
app.component.ts
#Component({
selector: 'my-app',
template: `
<navbar></navbar>
<jumbotron>My text to display</jumbotron>
`
,
directives: [NavbarComponent, JumbotronComponent]})
export class AppComponent { }

Adding to Luke's answer. You must import the Input annotation from
#angular/core
When using the #Input() annotation on a property. You can add a string as a parameter to reference the property with an alias.
Example:
#Input("customTitle")
Private title:string;
You can later use
<my-directive [customTitle]="Custom" > </my-directive>

Related

In Angular, can I add css style together with double curly brackets?

I am trying to create a style for my element using a variable name, which is a number, and adding % at the end. I am currently doing it inline like this:
<progress-bar
style="{{batteryLifeLeft+'%'}}"
/>
What is wrong with it? Can you not add things together in this expression? I am getting the error: "Property value expected" and "at-rule or selector expected."
Correct syntax would be [ngStyle]="{'width.%': batteryLifeLeft}". https://angular.io/api/common/NgStyle
<div style="width: {{ batteryLifeLeft }}%">
{{ batteryLifeLeft }}% this wont work
</div>
<br />
<div [ngStyle]="{ 'width.%': batteryLifeLeft }">
{{ batteryLifeLeft }}% this will work
</div>
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
batteryLifeLeft = 50;
constructor() {}
}
Working example is on StackBlitz

Is there a way to use either a nz-checkbox Or nz-checkbox-group Or nz-checkbox-wrapper inside a reactive form

Following code works great if is used independently,
<nz-checkbox-group [(ngModel)]="field.options" [formControlName]="field.id" (ngModelChange)="updateValue($event)"></nz-checkbox-group>
Angular6.0 does not allow [(ngModel)] with FormGroup (Reactive Forms). As is deprecated in angular 6.0 and will be removed in angular 7.0 version.
Is there any method to write nz-checkbox-group for ReactiveForm ?
I got a similar problem solved that using the following method. SourceCode
import { Component } from '#angular/core';
import { FormGroup, FormControl, FormBuilder, FormArray } from '#angular/forms';
#Component({
selector: 'nz-demo-checkbox-layout',
template: `
<nz-checkbox-wrapper style="width: 100%;" (nzOnChange)="log($event)">
<div nz-row >
<div [formGroup]="myFormGroup">
<label nz-checkbox nzValue="A" formControlName="a">A</label>
<label nz-checkbox nzValue="B" formControlName="b">B</label>
<label nz-checkbox nzValue="C" formControlName="c">C</label>
<label nz-checkbox nzValue="D" formControlName="d">D</label>
</div>
</div>
</nz-checkbox-wrapper>`
})
export class NzDemoCheckboxLayoutComponent {
constructor(private fb: FormBuilder) { }
public myFormGroup = this.fb.group({
a:this.fb.control(true),
b:this.fb.control(false),
c:this.fb.control(false),
d:this.fb.control(false)
});
}

Angular 'filter' style binding not work

There is an example
#Component({
selector: 'my-app',
template: `
<div>
<h2 style="background-color:green">
No Filter
</h2>
</div>
<div style="filter:brightness(0.5)">
<h2 style="background-color:green">
Filter with style.
</h2>
</div>
<div [style.filter]="'brightness(' + val + ')'">
<h2 style="background-color:green">
Filter with style binding.
</h2>
</div>
<p>filter binding express value: {{'brightness(' + val + ')'}}</p>
`,
})
export class App {
val = 0.5;
}
https://plnkr.co/edit/gD9xkX5aWrdNDyD6fnIh?p=preview
got the rendered result:
Seem like style binding [style.filter] not work. Anyone know the reason or give another way to control filter brightness style by component member value?
Thanks for any answer!
When we apply the filter style like this:
<div [style.filter]="'brightness(' + val + ')'">
the following message appears in the console:
WARNING: sanitizing unsafe style value brightness(0.5)
The style expression brightness(0.5) is considered unsafe by Angular. We can mark it as safe by calling DomSanitizer.bypassSecurityTrustStyle in a method of the component class or with the help of a custom pipe defined as:
import { Pipe } from "#angular/core";
import { DomSanitizer } from "#angular/platform-browser";
#Pipe({name: 'safe'})
export class SafePipe {
constructor(private sanitizer: DomSanitizer){
}
transform(style) {
return this.sanitizer.bypassSecurityTrustStyle(style);
}
}
which can be applied like this in the template:
<div [style.filter]="'brightness(' + val + ')' | safe">
An alternative, which does not involve sanitization problems, is to use the ngStyle directive:
<div [ngStyle]="{'filter': 'brightness(' + val + ')'}">
Both techniques are shown in this stackblitz.
The problem of unsafe style expressions has been discussed in other posts:
https://stackoverflow.com/a/38663363/1009922
https://stackoverflow.com/a/37267875/1009922

Angular 2 Adding html dynamically to DOM, style not working [duplicate]

This question already has answers here:
Angular 2 - innerHTML styling
(11 answers)
Closed 5 years ago.
Hello I am trying to add html from a file that is returned from the api, this is working. what I am needing help with is when I add an inline style it doesn't work, but if I create a class in the style.css it and add it to the html it then works.
All of this said, I need to get inline style working. I would like to get <span style="color:red;">I am red</span> working.
#Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<button (click)="onClick()">Click To Add Html</button>
</div>
<div *ngIf="html!==''" [innerHtml]="html"></div>
`,
})
export class App {
name:string;
html:string=null;
const htmlConst:string = `<span style="color:red;">I am red</span>`;
/*
I have tried [style] = "color:red;"
style="color:red;"
*/
constructor() {
this.name = `Angular! v${VERSION.full}`
}
onClick():void{
if(this.html !== ''){
this.html= this.htmlConst;
}
else{
this.html = '';
}
}
}
any advise would be helpful.
import { Component,ViewEncapsulation } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<button (click)="onClick()">Click To Add Html</button>
</div>
<div *ngIf="html!==''" [innerHtml]="html"></div>
`,
encapsulation: ViewEncapsulation.None
})
Please refer from https://toddmotto.com/emulated-native-shadow-dom-angular-2-view-encapsulation

Angular2 Bind Attribute Value

Similar to Angular2 two-way data binding, I have a parent and a child component. In the parent I change the value that is passed to the child component via property. The property of the child is named percentage.
https://gist.github.com/ideadapt/59c96d01bacbf3222096
I want to bind the property value to a html attribute value. Like: <div style="width: {{percentage}}%">. I didn't find any syntax that worked. So I ended up using a change listener that does some manual DOM update:
this.progressElement = DOM.querySelector(element.nativeElement, '.progress');
DOM.setAttribute(this.progressElement, "style", `width: ${this.percentage}%`);
Is there a more elegant way to accomplish this?
You can use percentage binding for CSS properties: [style.width.%]
import {Component, Input} from 'angular2/core';
#Component({
selector: 'progress-bar',
template: `
<div class="progress-bar">
<div [style.width.%]="value"> {{ value }}% </div>
</div>
`,
})
export class ProgressBar {
#Input() private value: number;
}
Use NgStyle, which works similar to Angular 1. Since alpha-30, NgStyle is available in angular2/directives:
import {NgStyle} from 'angular2/directives';
Then include NgStyle in the directives list, this should work (here are some examples):
#View({
directives: [NgStyle]
template: `
<div class="all">
<div class="progress" [ng-style]="{'width': percentage + '%'}"></div>
<span class="label">{{percentage}}</span>
</div>
`
})
Alternatively and without using NgStyle, this would work well too:
<div class="progress" [style.width]="percentage + '%'"></div>

Resources