我有以下组件:
@Component({
templateUrl: './signup.component.html'
})
export class SignupComponent implements OnInit {
signupForm: FormGroup; //Notice the FormGroup instance variable
submitted = false; //Also notice the submitted variable
...
使用自定义feedbackClasses
指令,如下所示(来自SignupComponent
模板):
<div class="form-group" [feedbackClasses]="signupForm" [control]="'firstName'" [submitted]="submitted">
以下是该指令的定义:
import {Directive, ElementRef, Input, Renderer, DoCheck} from '@angular/core';
import {AbstractControl, FormGroup} from '@angular/forms';
@Directive({selector: '[feedbackClasses]'})
export class FeedbackClassesDirective implements DoCheck {
@Input('feedbackClasses') formGroup: FormGroup;
@Input('control') controlPath: string; //I would like to avoid passing this as an attribute
@Input('submitted') submitted: boolean;//Same thing here
constructor(private el: ElementRef, private renderer: Renderer) {
}
ngDoCheck() {
const control: AbstractControl = this.formGroup.get(this.controlPath);
if (control && this.submitted) {
this.applyClasses(control.invalid);
}
}
private applyClasses(inError: boolean) {
this.renderer.setElementClass(this.el.nativeElement, 'has-success', !inError);
this.renderer.setElementClass(this.el.nativeElement, 'has-danger', inError);
}
}
我遇到的问题是,每次我想使用此指令时,我都必须传入相应的FormGroup
和boolean
,表明表单是否已提交。
有没有办法直接从指令中检索FormGroup
和boolean
而不使用属性?如果是这样的话?
答案 0 :(得分:1)
您可以注入应用指令的组件。 为此,该指令只能应用于一种类型的组件。
@Directive({selector: '[feedbackClasses]'})
export class FeedbackClassesDirective implements DoCheck {
@Input('feedbackClasses') formGroup: FormGroup;
@Input('control') controlPath: string; //I would like to avoid passing this as an attribute
@Input('submitted') submitted: boolean;//Same thing here
constructor(private el: ElementRef,
private renderer: Renderer,
private signUpComponent: SignupComponent) {
}
ngOnInit() {
console.log(this.signUpComponent.signUpForm);
console.log(signUpComponent.submitted); // probably not set yet
}
}
或者您可以在应该支持该指令的组件上提供共享服务并将其注入
@Injectable()
export class FormStatusService {
signupForm: FormGroup;
submitted = false; // better use an BehaviorSubject
}
@Component({
templateUrl: './signup.component.html':
providers: [FormStatusService]
})
export class SignupComponent implements OnInit {
//signupForm: FormGroup; //Notice the FormGroup instance variable
//submitted = false; //Also notice the submitted variable
constructor(private formStatus:FormStatusService) {
// access shared service to read and write values
}
...
}
@Directive({selector: '[feedbackClasses]'})
export class FeedbackClassesDirective implements DoCheck {
// @Input('feedbackClasses') formGroup: FormGroup;
// @Input('control') controlPath: string; //I would like to avoid passing this as an attribute
// @Input('submitted') submitted: boolean;//Same thing here
constructor(private el: ElementRef,
private renderer: Renderer,
private signUpComponent: FormStatusService) {
// access shared service to read and write values
}
}
另见https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service