如何在Ionic的Service中调用Component的updateSelectItem方法?
Got it, the key here is to pass the component's callback method directly to your service's presentActionSheet function. This way, the service can trigger the component-specific logic when an Action Sheet button is clicked, without repeating code across multiple select components.
Step 1: Update the ActionSheetService to accept a callback
Modify your service's presentActionSheet method to add a parameter for the callback function that handles the selection. This keeps the service generic while letting it trigger component-specific behavior.
import { Injectable } from '@angular/core'; import { ActionSheetController } from 'ionic-angular' @Injectable() export class ActionSheetService { constructor(private actionSheetCtrl: ActionSheetController) { } // Add a callback parameter to the method signature public presentActionSheet( actionTitle: string, items: any[], onItemSelected: (id: number, item: any) => void // New callback parameter ): void { let actionSheet = this.actionSheetCtrl.create({ title: actionTitle }); for (let i = 0; i < items.length; i++) { actionSheet.addButton({ text: items[i].name, cssClass: items[i].css, icon: items[i].selectIcon, handler: () => { // Call the passed-in callback here with selection data onItemSelected(i, items[i]); console.log('Service ActionHandler'); } }); } actionSheet.addButton({ text: 'Cancel', 'role': 'cancel' }); actionSheet.present(); } }
Step 2: Pass the component's method to the service
In your TypeSelectComponent, update the presentActionSheet call to pass the updateSelectItem method (with proper this context) to the service. Using an arrow function ensures this refers to the component instance, not the service.
import { Component, EventEmitter, Input, Output } from '@angular/core'; import { ActionSheetService } from '../../services/action-sheet.service'; import { Type } from '../../models/general/type.model'; @Component({ selector: 'type-select-component', templateUrl: 'type-select.component.html', providers: [ ActionSheetService ] }) export class TypeSelectComponent { @Input() public types: Object[]; @Output() public typeId: EventEmitter<number> = new EventEmitter<number>(); public updatedItem: Type = new Type(); private actionTitle: string = "What's Type" constructor( private actionSheetService: ActionSheetService ) { } public updateSelectItem(id:number, type: Type): void{ this.updatedItem = type; this.typeId.emit(id); } public presentActionSheet(): void { // Pass the component's handler via arrow function to preserve context this.actionSheetService.presentActionSheet( this.actionTitle, this.types as Type[], (id, type) => this.updateSelectItem(id, type) ); } }
Alternative: Bind this directly
If you prefer not to use an arrow function, you can bind this when passing the method to the service:
this.actionSheetService.presentActionSheet( this.actionTitle, this.types as Type[], this.updateSelectItem.bind(this) );
Both approaches work—pick the one that aligns with your coding style. This solution keeps your Action Sheet logic centralized (following DRY) while letting each select component maintain its own update behavior.
内容的提问来源于stack exchange,提问作者Rafael de Castro

