Reputation: 219
I have some buttons in an Ionic 3 app that I would like to be able to dynamically set as outline or clear. I can bind clear
by itself and that works (case 1 below). And I can bind outline
by itself (case 2 below). But when I try to bind both clear
and outline
it seems like the value of outline
gets ignored. I've shown my desired output in the very last row.
I have this as part of the class for my page:
buttons = [
{clear: true, outline: false, name: 'Clear'},
{clear: false, outline: true, name: 'Outline'},
{clear: false, outline: false, name: 'Default'},
];
And my HTML is:
<ion-content padding>
<ion-row>
<ion-col col-6>
<ion-label>
1. Binding clear attribute:
</ion-label>
</ion-col>
<ion-col col-2 *ngFor="let button of buttons">
<button ion-button
[clear]="button.clear">
{{button.name}}
</button>
</ion-col>
</ion-row>
<ion-row>
<ion-col col-6>
<ion-label>
2. Binding outline attribute:
</ion-label>
</ion-col>
<ion-col col-2 *ngFor="let button of buttons">
<button ion-button
[outline]="button.outline">
{{button.name}}
</button>
</ion-col>
</ion-row>
<ion-row>
<ion-col col-6>
<ion-label>
3. Binding clear and outline attributes:
</ion-label>
</ion-col>
<ion-col col-2 *ngFor="let button of buttons">
<button ion-button
[outline]="button.outline"
[clear]="button.clear">
{{button.name}}
</button>
</ion-col>
</ion-row>
<ion-row>
<ion-col col-6>
<ion-label>
4. Desired output:
</ion-label>
</ion-col>
<ion-col col-2>
<button ion-button clear>Clear</button>
</ion-col>
<ion-col col-2>
<button ion-button outline>Outline</button>
</ion-col>
<ion-col col-2>
<button ion-button>Default</button>
</ion-col>
</ion-row>
</ion-content>
Here is a rendering of the page:
And a Plunker with the full code: https://embed.plnkr.co/eFBFc9/
Is there a reason I shouldn't be able to bind to both clear
and outline
?
I realize I could use an ngIf
to ultimately achieve the same result:
<button ion-button *ngIf="button.clear" clear>{{button.name}}</button>
<button ion-button *ngIf="button.outline" outline>{{button.name}}</button>
<button ion-button *ngIf="!button.clear && !button.outline">{{button.name}}</button>
But it seems like it would be more concise to have one button with multiple bound attributes. How can I achieve this?
I also tried attr.clear
and attr.outline
in place of clear
and outline
but had no luck with that either.
Upvotes: 1
Views: 2341
Reputation: 44659
This looks like a bug in Ionic, but still you can create your own custom component to "hide" the fix that involves using three buttons with the *ngIf
and use that custom component in your pages.
Your custom component could look like this for example:
import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'custom-button',
template: `
<button (click)="onClick()" ion-button *ngIf="clear" clear>{{name}}</button>
<button (click)="onClick()" ion-button *ngIf="outline" outline>{{name}}</button>
<button (click)="onClick()" ion-button *ngIf="!clear && !outline">{{name}}</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CustomButtonComponent {
@Input()
public clear: boolean = false;
@Input()
public outline: boolean = false;
@Input()
public name: string;
@Output()
customClick: EventEmitter<void> = new EventEmitter<void>();
public onClick(): void {
this.customClick.next();
}
}
And then you'd use it like this in your pages:
import { Component } from '@angular/core';
@Component({
selector: 'page-home',
template: `
<ion-header>
<ion-navbar>
<ion-title>Home</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Welcome to Ionic!</h2>
<ion-row>
<ion-col col-6>
<ion-label>
Using the custom component:
</ion-label>
</ion-col>
<ion-col col-2 *ngFor="let button of buttons">
<custom-button
[clear]="button.clear ? true : null"
[outline]="button.outline ? true : null"
[name]="button.name"
(customClick)="onClicked()">
</custom-button>
</ion-col>
</ion-row>
</ion-content>
`
})
export class HomePage {
public buttons: Array<any> = [
{ clear: true, outline: false, name: 'Clear' },
{ clear: false, outline: true, name: 'Outline' },
{ clear: false, outline: false, name: 'Default' }
];
public onClicked() {
console.log('Clicked!');
}
}
Upvotes: 1