从指令中检索主机组件的 FormGroup 变量而不将其作为属性传递
Retrieving a host component's FormGroup variable from a directive without passing it as an attribute
我有以下组件:
@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
?如果有怎么办?
您可以注入应用指令的组件。
为此,该指令只能应用于一种类型的组件。
@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
我有以下组件:
@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
?如果有怎么办?
您可以注入应用指令的组件。 为此,该指令只能应用于一种类型的组件。
@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