手动将服务注入组件的指令中

时间:2017-03-06 10:15:17

标签: angular typescript2.0

我有指令

     @Directive({
      selector:'[appAsyncNameValidator][formControlName],[appAsyncNameValidator][ngModel]',
      providers: [
        {
          provide: NG_ASYNC_VALIDATORS,
          useExisting: forwardRef(() => AsyncNameValidatorDirective), multi: true
        }
      ]
    })

    export class AsyncNameValidatorDirective implements Validator {
       constructor(private service: any service that implements IForValidation) {
       }

      validate(c: AbstractControl): Observable<any> {
         return doSomethig(c); // => use in doSomethig service.getByName(c.value) 
      }
    }

export interface IForValidation{
       getByName(name: string);
    }

和组件

@Component({
  selector: 'app-edit-role',
  template: `<input type="text" class="form-control" id="roleName" name="roleName" 
             placeholder="Role name..." [(ngModel)]="role.name" appAsyncNameValidator 
             required #roleName="ngModel">`,
  styleUrls: ['./edit-role.component.scss']
})

export class EditRoleComponent implements OnInit {
    constructor() {
    }
}

我想让这个指令对所有服务都是通用的。如何从组件中将任何服务注入指令?

2 个答案:

答案 0 :(得分:1)

您可以定义界面IRoleService

export interface IRoleService {
    getRoles(uid:string):Role[];
    ...
}

const IRoleService = new OpaqueToken("IRoleService");

设置接口与具体类的绑定:

@NgModule({
    providers: [{
         provide: IRoleService,
         useClass: RoleService
    }]
})

像这样注射:

constructor(@Inject(IRoleService) roleService:IRoleService).

答案 1 :(得分:0)

修改

我已将下一个输入添加到指令

@Input() service: any;

@Input() methodName: string;

并在我的doSomethig(c)方法中像这样使用它:

this.service[this.methodName](value);

在组件中,您必须以另一种方式使用它:

<input type="text" class="form-control" id="roleName" name="roleName" placeholder="Role name..." 

          [(ngModel)]="role.name" appAsyncNameValidator [service]="roleService" [methodName]="'methodName'"

          required #roleName="ngModel">

希望这对某人有帮助。