I need to add the isBold
property to an Angular component
<child-component isBold />
Remark the following
I prefer do not use square brackets [] around the property name if used as
true
flag (as in the code above, long version would beisBold = true
).However I would like to be able to use it as an input property
<child-component [isBold]="parentBooleanOrFunction" />
the code bellow breaks the first requirement
@Input() isBold: boolean = true
Is there a way, in Angular 13, to do it without writing additional helper functions?
I note I read the similar question here, but the selected solution needs additional code or Material usage I have not.
CodePudding user response:
You can use directive to do that but it will not work as an ordinary @Input
Working examople on stackblitz
Create input directive
@Directive({
selector: '[isBold]'
})
export class IsBoldDirective {
@Input() isBold:boolean;
constructor() { }
ngOnInit(){
if(this.isBold!==false){
this.isBold=true; // defaults to true
}
}
}
Inject it into the component
@Component({
selector: 'app-testing',
templateUrl: './testing.component.html',
styleUrls: ['./testing.component.css']
})
export class TestingComponent {
constructor(@Self() @Optional() private isBold:IsBoldDirective) { }
get value(){
return this.isBold?.isBold ?? true; // this 'true' is the default value if isBold is not there
}
}
and use it like this
Absence: <app-testing></app-testing>
Presence: <app-testing isBold></app-testing>
Set value: <app-testing [isBold]="false"></app-testing>
with result
Absence:
true
Presence:
true
Set value:
false
CodePudding user response:
To achieve that, I would suggest creating your own coercion
functions/types similar to the Angular CDK functions/types (If you don't need to add the @angular/cdk
to your project dependencies), which are very easy to implement than creating a directive for each Input:
/**
* Type describing the allowed values for a boolean input.
* @docs-private
*/
export type BooleanInput = string | boolean | null | undefined;
/** Coerces a data-bound value (typically a string) to a boolean. */
export function coerceBooleanProperty(value: any): boolean {
return value != null && `${value}` !== 'false';
}
Then you can use them directly in any component, like the following:
@Input()
get isBold(): boolean {
return this._isBold;
}
set isBold(isBold: BooleanInput) {
this._isBold = coerceBooleanProperty(isBold);
}
private _isBold = false;
<child-component isBold />
<child-component [isBold]="parentBooleanOrFunction" />
You can find the full list of Angular CDK coercion
functions/types under angular/components/src/cdk/coercion/
:
https://github.com/angular/components/tree/main/src/cdk/coercion