问题
Hi how to avoid the ok and cancel button in ion-options?
I need an output as the below image after clicking the ion-option.
I have tried all the options as per http://ionicframework.com/docs/v2/api/components/select/Select/.
Yet I am not able to achieve this ui.
Even after typing interface="action-sheet"
I am not able to achieve the wanted look.
Where can I find a demo or any help to get this view?
回答1:
This question was actually something I myself needed and I know some people have needed it for a while. So I hope this helps..
OPTION 1: WRAPPED SUPER COMPONENT
First we are creating a component called select-alertless. Here is the HTML that has the options:
<ion-select [(ngModel)]="model" #select>
<ion-option *ngFor="let option options" [value]="option.id">{{option.name}}</ion-option>
</ion-select>
Really simple with a link for a view child.
Now the scss to hide the ok/cancel buttons:
.select-alertless{
.alert-button-group{
display:none;
}
}
The actual component class which looks for sets on the select inside the html. Looks for the options and sets an emit on the clicks. Thus everytime someone clicks one of the options it. The open function is just here to dismiss the alert after you click.
@Component({
templateUrl: 'select-alertless.html',
selector: 'select-alertless',
})
export class select_alertless {
// the options that are displayed
@Input('options') public options: any[];
@Input('model') public model: any;
// the event that is to be emitted when changes occures
@Output('change') public change: EventEmitter<any> = new EventEmitter<any>();
// The sets here capture events and emit the data to change when its needed. It also switched the open function for our own open function so then the viewcontroller can be closed.
@ViewChild('select') public set ex(select: any | undefined) {
if (select === undefined) return;
select.open = this.open;
if (select._options === undefined) {
Object.defineProperty(select, '_options', {
set: (val) => {
select['__options'] = val;
val.forEach(option => option.ionSelect.subscribe(d => {
this.change.emit(d);
this.model = d;
select.overlay.dismiss();
}));
},
get: function () { return select['__options'] }
})
}
}
open() {
if ((<any>this)._disabled) {
return;
}
console.debug('select, open alert');
// the user may have assigned some options specifically for the alert
const selectOptions = deepCopy((<any>this).selectOptions);
// make sure their buttons array is removed from the options
// and we create a new array for the alert's two buttons
selectOptions.buttons = [{
text: (<any>this).cancelText,
role: 'cancel',
handler: () => {
(<any>this).ionCancel.emit(null);
}
}];
// if the selectOptions didn't provide a title then use the label's text
if (!selectOptions.title && (<any>this)._item) {
selectOptions.title = (<any>this)._item.getLabelText();
}
let options = (<any>this)._options.toArray();
// default to use the alert interface
(<any>this).interface = 'alert';
// user cannot provide inputs from selectOptions
// alert inputs must be created by ionic from ion-options
selectOptions.inputs = (<any>this)._options.map(input => {
return {
type: ((<any>this)._multi ? 'checkbox' : 'radio'),
label: input.text,
value: input.value,
checked: input.selected,
disabled: input.disabled,
handler: (selectedOption: any) => {
// Only emit the select event if it is being checked
// For multi selects this won't emit when unchecking
if (selectedOption.checked) {
input.ionSelect.emit(input.value);
}
}
};
});
var selectCssClass = 'select-alert';
// create the alert instance from our built up selectOptions
(<any>this).overlay = new Alert((<any>(<any>this))._app, selectOptions);
if ((<any>this)._multi) {
// use checkboxes
selectCssClass += ' multiple-select-alert select-alertless';
} else {
// use radio buttons
selectCssClass += ' single-select-alert select-alertless';
}
// If the user passed a cssClass for the select, add it
selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
(<any>this).overlay.setCssClass(selectCssClass);
(<any>this).overlay.addButton({
text: (<any>this).okText,
handler: (selectedValues: any) => {
(<any>this).onChange(selectedValues);
(<any>this).ionChange.emit(selectedValues);
}
});
(<any>this).overlay.present(selectOptions);
(<any>this)._isOpen = true;
(<any>this).overlay.onDidDismiss(() => {
(<any>this)._isOpen = false;
});
}
}
This answer would've been a lot shorter if the created alert in select was public rather than a local variable.
Add this to your app module and you are free to use it. Here is an example:
<ion-item>
<ion-label>stuff</ion-label>
<select-alertless [model]="data" item-content [options]="options" (change)="data = $event"></select-alertless>
</ion-item>
You can add more inputs that are passed to the ion-select to have more configuration.
OPTION 2: EXTEND SELECT ITSELF
This would be a better solution since it gives you the option to just write the component like ion-select only select-alertless
import { AfterContentInit, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, Input, HostListener, OnDestroy, Optional, Output, Renderer, QueryList, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ActionSheet, Alert, App, Config, Form, Ion, Item, NavController, Option, ViewController } from 'ionic-angular';
import { isBlank, isCheckedProperty, isTrueProperty, deepCopy } from 'ionic-angular/util/util';
import { Select as ImportSelect } from 'ionic-angular/components/select/select';
export class TempSelect extends ImportSelect {
static decorators = undefined;
// static propDecorators = undefined;
}
export const SELECT_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Select),
multi: true
};
@Component({
selector: 'select-alertless',
styles: ['.select-alertless .alert-button-group{display:none}'],
template:
'<div *ngIf="!_text" class="select-placeholder select-text">{{placeholder}}</div>' +
'<div *ngIf="_text" class="select-text">{{selectedText || _text}}</div>' +
'<div class="select-icon">' +
'<div class="select-icon-inner"></div>' +
'</div>' +
'<button aria-haspopup="true" ' +
'[id]="id" ' +
'ion-button="item-cover" ' +
'[attr.aria-labelledby]="_labelId" ' +
'[attr.aria-disabled]="_disabled" ' +
'class="item-cover">' +
'</button>',
host: {
'[class.select-disabled]': '_disabled'
},
providers: [SELECT_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None,
})
export class Select extends TempSelect implements AfterContentInit, ControlValueAccessor, OnDestroy {
public overlay: Alert;
private __options: any;
constructor(
_app: App,
_form: Form,
config: Config,
elementRef: ElementRef,
renderer: Renderer,
@Optional() public _item: Item,
@Optional() _nav: NavController
) {
super(_app, _form, config, elementRef, renderer, _item, _nav);
this.setElementClass(`${this._componentName}-${this._mode}`, false);
}
public set _options(val) {
this.__options = val;
if (!this._multi) {
this.__options.forEach(option => {
option.ionSelect.subscribe(selectedValues => {
this.onChange(selectedValues);
this.ionChange.emit(selectedValues);
this._isOpen = false;
this.overlay.dismiss();
});
});
}
}
public get _options() {
return this.__options;
}
open() {
if (this._disabled) {
return;
}
// the user may have assigned some options specifically for the alert
const selectOptions = deepCopy(this.selectOptions);
// make sure their buttons array is removed from the options
// and we create a new array for the alert's two buttons
selectOptions.buttons = [{
text: this.cancelText,
role: 'cancel',
handler: () => {
this.ionCancel.emit(null);
}
}];
// if the selectOptions didn't provide a title then use the label's text
if (!selectOptions.title && this._item) {
selectOptions.title = this._item.getLabelText();
}
let options = this._options.toArray();
// default to use the alert interface
this.interface = 'alert';
// user cannot provide inputs from selectOptions
// alert inputs must be created by ionic from ion-options
selectOptions.inputs = this._options.map(input => {
return {
type: (this._multi ? 'checkbox' : 'radio'),
label: input.text,
value: input.value,
checked: input.selected,
disabled: input.disabled,
handler: (selectedOption: any) => {
// Only emit the select event if it is being checked
// For multi selects this won't emit when unchecking
if (selectedOption.checked) {
input.ionSelect.emit(input.value);
}
}
};
});
var selectCssClass = 'select-alert';
// create the alert instance from our built up selectOptions
this.overlay = new Alert((<any>this)._app, selectOptions);
if (this._multi) {
// use checkboxes
selectCssClass += ' multiple-select-alert';
} else {
// use radio buttons
selectCssClass += ' single-select-alert select-alertless';
}
// If the user passed a cssClass for the select, add it
selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
this.overlay.setCssClass(selectCssClass);
this.overlay.addButton({
text: this.okText,
handler: (selectedValues: any) => {
this.onChange(selectedValues);
this.ionChange.emit(selectedValues);
}
});
this.overlay.present(selectOptions);
this._isOpen = true;
this.overlay.onDidDismiss(() => {
this._isOpen = false;
});
}
}
Use like:
<select-alertless item-content [(ngModel)]="data"><ion-option></ion-option></select-alertless>
Basically use like normal select
For more information and an example project on how to use it consult this github: https://github.com/misha130/ionic2-select-nobuttons
来源:https://stackoverflow.com/questions/40925172/how-to-avoid-ok-cancel-button-in-ion-option-ion-select