<p dir="auto"><strong>I'm submitting a ...</strong>  (check one with "x")</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" code  HeroFormComponent .ts
import { Component} from '@angular/core';
import { FormControl, FormGroup, Validators,FormBuilder } from '@angular/forms';
import { ValidationService } from './validation.service';
@Component({
  selector: 'hero-form',
  templateUrl: 'app/hero-form.component.html'
    template: `
 &lt;form [formGroup]=&quot;form&quot; (ngSubmit)=&quot;onSubmit()&quot;&gt;

      &lt;div formGroupName=&quot;name&quot;&gt;
        &lt;input formControlName=&quot;first&quot; placeholder=&quot;First name&quot;&gt;
        &lt;input formControlName=&quot;last&quot; placeholder=&quot;Last name&quot;&gt;
      &lt;/div&gt;  
      &lt;input formControlName=&quot;email&quot; placeholder=&quot;Email&quot;&gt;
      &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
    &lt;/form&gt;
 `,
})

export class HeroFormComponent {
  form: any;
  constructor(private _formBuilder: FormBuilder) {
    this.form = new FormGroup({
      name: new FormGroup({
        first: new FormControl('Nancy',Validators.compose([Validators.required,ValidationService.codeValidator])),
        last: new FormControl('Drew',Validators.compose([Validators.required,ValidationService.codeValidator]))
      }),
      email: new FormControl('kjA001', Validators.compose([Validators.required]))
    }); 
  }

code  ValidationService.ts
export class ValidationService {
    static getValidatorErrorMessage(code: string) {
        let config = {
            'required': '该字段必填', 
            'invalidCode': '验证码错误!', 
        };
        return config[code];
    }

    static codeValidator(control) { 
        // 验证码
        if (control.value.match(/^[0-9]{6}$/)) {
            return null;
        } else { 
            return { 'invalidCode': true };
        }
    }
}




https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question"><pre class="notranslate"><code class="notranslate"> code  HeroFormComponent .ts
import { Component} from '@angular/core';
import { FormControl, FormGroup, Validators,FormBuilder } from '@angular/forms';
import { ValidationService } from './validation.service';
@Component({
  selector: 'hero-form',
  templateUrl: 'app/hero-form.component.html'
    template: `
 &lt;form [formGroup]="form" (ngSubmit)="onSubmit()"&gt;

      &lt;div formGroupName="name"&gt;
        &lt;input formControlName="first" placeholder="First name"&gt;
        &lt;input formControlName="last" placeholder="Last name"&gt;
      &lt;/div&gt;  
      &lt;input formControlName="email" placeholder="Email"&gt;
      &lt;button type="submit"&gt;Submit&lt;/button&gt;
    &lt;/form&gt;
 `,
})

export class HeroFormComponent {
  form: any;
  constructor(private _formBuilder: FormBuilder) {
    this.form = new FormGroup({
      name: new FormGroup({
        first: new FormControl('Nancy',Validators.compose([Validators.required,ValidationService.codeValidator])),
        last: new FormControl('Drew',Validators.compose([Validators.required,ValidationService.codeValidator]))
      }),
      email: new FormControl('kjA001', Validators.compose([Validators.required]))
    }); 
  }

code  ValidationService.ts
export class ValidationService {
    static getValidatorErrorMessage(code: string) {
        let config = {
            'required': '该字段必填', 
            'invalidCode': '验证码错误!', 
        };
        return config[code];
    }

    static codeValidator(control) { 
        // 验证码
        if (control.value.match(/^[0-9]{6}$/)) {
            return null;
        } else { 
            return { 'invalidCode': true };
        }
    }
}




https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
</code></pre></div>
<p dir="auto"><strong>Current behavior</strong></p>

<p dir="auto">When change the input frame's error value<br>
this.form.errors  is null</p>
<p dir="auto"><strong>Expected behavior</strong></p>

<p dir="auto">this.form.errors  show the current error:  { 'invalidCode': true }</p>
<p dir="auto"><strong>Reproduction of the problem</strong></p>
<p dir="auto">Have so a piece of code in the source code:</p>
<p dir="auto">dir.valueAccessor.registerOnChange(function (newValue) {<br>
dir.viewToModelUpdate(newValue);<br>
control.markAsDirty();<br>
control.setValue(newValue, { emitModelToViewChange: false });<br>
});</p>
<p dir="auto">FormControl.prototype.setValue = function (value, _a) {<br>
var _this = this;<br>
var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent, emitModelToViewChange = _b.emitModelToViewChange, emitViewToModelChange = _b.emitViewToModelChange;<br>
emitModelToViewChange = isPresent(emitModelToViewChange) ? emitModelToViewChange : true;<br>
emitViewToModelChange = isPresent(emitViewToModelChange) ? emitViewToModelChange : true;<br>
this._value = value;<br>
if (this._onChange.length &amp;&amp; emitModelToViewChange) {<br>
this._onChange.forEach(function (changeFn) { return changeFn(_this._value, emitViewToModelChange); });<br>
}<br>
this.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent });<br>
};</p>
<p dir="auto">The inside of the source onlySelf  is undefined<br>
onlySelf:false;</p>
<p dir="auto">Continue to the source code below   this.updateValueAndValidity</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="AbstractControl.prototype.updateValueAndValidity = function (_a) {
        var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent;
        onlySelf = normalizeBool(onlySelf);
        emitEvent = isPresent(emitEvent) ? emitEvent : true;
        this._setInitialStatus();
        this._updateValue();
        if (this.enabled) {
            this._errors = this._runValidator();
            this._status = this._calculateStatus();
            if (this._status === VALID || this._status === PENDING) {
                this._runAsyncValidator(emitEvent);
            }
        }
        if (emitEvent) {
            this._valueChanges.emit(this._value);
            this._statusChanges.emit(this._status);
        }
        if (isPresent(this._parent) &amp;&amp; !onlySelf) {
            this._parent.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent });
        }
    };"><pre class="notranslate"><code class="notranslate">AbstractControl.prototype.updateValueAndValidity = function (_a) {
        var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent;
        onlySelf = normalizeBool(onlySelf);
        emitEvent = isPresent(emitEvent) ? emitEvent : true;
        this._setInitialStatus();
        this._updateValue();
        if (this.enabled) {
            this._errors = this._runValidator();
            this._status = this._calculateStatus();
            if (this._status === VALID || this._status === PENDING) {
                this._runAsyncValidator(emitEvent);
            }
        }
        if (emitEvent) {
            this._valueChanges.emit(this._value);
            this._statusChanges.emit(this._status);
        }
        if (isPresent(this._parent) &amp;&amp; !onlySelf) {
            this._parent.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent });
        }
    };
</code></pre></div>

<p dir="auto"><strong>What is the motivation / use case for changing the behavior?</strong></p>

<p dir="auto"><strong>Please tell us about your environment:</strong></p>

<ul dir="auto">
<li>
<p dir="auto"><strong>Angular version:</strong> 2.0.0</p>

</li>
<li>
<p dir="auto"><strong>Browser:</strong> [Chrome ]</p>

</li>
<li>
<p dir="auto"><strong>Language:</strong> [TypeScript ]</p>
</li>
<li>
<p dir="auto"><strong>Node (for AoT issues):</strong> <code class="notranslate">node --version</code> =</p>
</li>
</ul>
<p dir="auto"><strong>I'm submitting a ...</strong>  (check one with "x")</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[ ] bug report
[x feature request
[ ] support request =&gt; Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question"><pre class="notranslate"><code class="notranslate">[ ] bug report
[x feature request
[ ] support request =&gt; Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
</code></pre></div>
<p dir="auto"><strong>Current behavior</strong><br>
When there are errors in a form group, the formGroup.status is 'INVALID' but the formGroup.errors property is null.</p>
<p dir="auto">ex.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="formGroup.controls.username.errors: {invalidEmail: true}
formGroup.errors: null"><pre class="notranslate"><code class="notranslate">formGroup.controls.username.errors: {invalidEmail: true}
formGroup.errors: null
</code></pre></div>
<p dir="auto"><strong>Expected/desired behavior</strong><br>
When the validity of a FormControl changes, have the parent FormGroup.errors merged with the errors from the controls. This is similar to how the angularjs formController.$error property works.<br>
<a href="https://docs.angularjs.org/api/ng/type/form.FormController" rel="nofollow">https://docs.angularjs.org/api/ng/type/form.FormController</a></p>
<p dir="auto"><strong>What is the motivation / use case for changing the behavior?</strong><br>
This would be helpful because I prefer to only disable a submit button when specific errors are on a form, such as required. With this I could drive that attribute off the formControl.errors value instead of formControl.status.</p>
<p dir="auto">ex.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="From:
&lt;button [disabled]=&quot;myForm.status !== 'VALID'&quot;&gt;Submit&lt;/button&gt;

To: 
&lt;button [disabled]=&quot;myForm.errors.required&quot;&gt;Submit&lt;/button&gt;"><pre class="notranslate"><code class="notranslate">From:
&lt;button [disabled]="myForm.status !== 'VALID'"&gt;Submit&lt;/button&gt;

To: 
&lt;button [disabled]="myForm.errors.required"&gt;Submit&lt;/button&gt;
</code></pre></div>