如何根据@Input值在Angular组件中条件注入服务
基于@Input值条件注入Angular服务的解决方案
首先纠正你代码里的一个错误:@Input() 装饰器必须放在组件类内部的属性上,而不是类外面,否则无法生效。
方案一:初始化时固定策略(适合isStrategy不动态变化的场景)
这种方式在组件注入器初始化时,根据isStrategy的初始值决定使用自定义策略还是默认策略:
1. 修正组件类的@Input位置并配置动态提供者
import { Component, Self, Optional } from '@angular/core'; import { MAT_DATE_RANGE_SELECTION_STRATEGY, MatDateRangeSelectionStrategy } from '@angular/material/datepicker'; import { DateAdapter } from '@angular/material/core'; import { FiveDayRangeSelectionStrategy } from './service'; @Component({ selector: 'date-range-picker-selection-strategy-example', templateUrl: 'date-range-picker-selection-strategy-example.html', providers: [ { provide: MAT_DATE_RANGE_SELECTION_STRATEGY, useFactory: (component: DateRangePickerSelectionStrategyExample, defaultStrategy: MatDateRangeSelectionStrategy<any>) => { // 根据组件的isStrategy值选择对应策略 return component.isStrategy ? new FiveDayRangeSelectionStrategy(component.dateAdapter) : defaultStrategy; }, // 依赖注入配置:当前组件实例、可选的默认策略(跳过自身注入避免循环) deps: [DateRangePickerSelectionStrategyExample, [new Optional(), new Self(), MAT_DATE_RANGE_SELECTION_STRATEGY]], }, ], }) export class DateRangePickerSelectionStrategyExample { @Input() isStrategy: boolean = false; constructor(public dateAdapter: DateAdapter<any>) {} }
方案二:支持动态切换策略(适合isStrategy可能在组件生命周期中变化的场景)
如果isStrategy的值可能在组件运行时改变,需要用一个包装类来动态切换策略:
1. 创建动态策略包装服务
import { Injectable } from '@angular/core'; import { MatDateRangeSelectionStrategy, DateRange } from '@angular/material/datepicker'; import { FiveDayRangeSelectionStrategy } from './service'; @Injectable() export class DynamicRangeSelectionStrategy<D> implements MatDateRangeSelectionStrategy<D> { private currentStrategy: MatDateRangeSelectionStrategy<D>; constructor( private defaultStrategy: MatDateRangeSelectionStrategy<D>, private fiveDayStrategy: FiveDayRangeSelectionStrategy<D> ) { // 默认使用系统内置策略 this.currentStrategy = defaultStrategy; } // 对外暴露的策略切换方法 setUseCustomStrategy(useCustom: boolean): void { this.currentStrategy = useCustom ? this.fiveDayStrategy : this.defaultStrategy; } // 代理策略核心方法 selectionFinished(date: D | null): DateRange<D> { return this.currentStrategy.selectionFinished(date); } createPreview(activeDate: D | null): DateRange<D> { return this.currentStrategy.createPreview(activeDate); } }
2. 修改组件配置与逻辑
import { Component, Input } from '@angular/core'; import { MAT_DATE_RANGE_SELECTION_STRATEGY } from '@angular/material/datepicker'; import { FiveDayRangeSelectionStrategy } from './service'; import { DynamicRangeSelectionStrategy } from './dynamic-selection-strategy'; @Component({ selector: 'date-range-picker-selection-strategy-example', templateUrl: 'date-range-picker-selection-strategy-example.html', providers: [ FiveDayRangeSelectionStrategy, { provide: MAT_DATE_RANGE_SELECTION_STRATEGY, useClass: DynamicRangeSelectionStrategy, }, ], }) export class DateRangePickerSelectionStrategyExample { private _isStrategy = false; @Input() set isStrategy(value: boolean) { this._isStrategy = value; // 输入值变化时实时切换策略 this.dynamicStrategy.setUseCustomStrategy(value); } get isStrategy(): boolean { return this._isStrategy; } constructor(private dynamicStrategy: DynamicRangeSelectionStrategy<any>) {} }
两种方案的区别:
- 方案一仅在组件初始化时生效一次,后续
isStrategy变化不会改变策略; - 方案二支持实时响应
isStrategy的变化,动态切换服务实现。
内容的提问来源于stack exchange,提问作者Hamza Haddad
相关产品推荐
相关产品推荐

