首页 文章

在Angular 2中订阅valueChanges的正确方法

提问于
浏览
6

我一直在调整Angular 2中的反应形式和订阅 . 我不知道为什么某些形式的订阅似乎不被允许 .

this.form.get('name').valueChanges /* <- doesn't work */
  .do(changes => {
    console.log('name has changed:', changes)
    });
  .subscribe();

this.form.get('title').valueChanges.subscribe( /* <- does work */
  changes => console.log('title has changed:', changes)
);

This plunker重现问题(打开DevTools控制台以查看错误):

ZoneAwareError {stack:“错误:未捕获(承诺):TypeError:不能se...g.com/zone.js@0.7.5/dist/zone.js:349:25)[]”,消息:“未捕获(在promise中:TypeError:无法设置prope ... ore.umd.js:8486:93)↵在Array.forEach(native)“,originalStack:”错误:未捕获(在promise中):TypeError:不能se ... ps:// unpkg.com/zone.js@0.7.5/dist/zone.js:349:25)“,zoneAwareStack:”错误:未捕获(承诺):TypeError:不能se...g.com/zone.js@0.7 . 5 / dist / zone.js:349:25)[]“,名称:”错误“......}

第一种模式(带有 do )确实不违法吗?

3 回答

  • 2

    这使你的plunker工作:

    • 在app.ts中添加此import语句

    import'rxjs / add / operator / do';

    • 在.do语句后删除分号

    .do(更改=> {console.log('名称已更改:',更改)})

    完成更改的应用程序

    import {Component, NgModule, OnInit} from '@angular/core'
    import {BrowserModule } from '@angular/platform-browser'
    import { FormGroup, FormBuilder, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
    import { Observable } from 'rxjs/Observable';
    import { Subscription } from 'rxjs/Subscription';
    import 'rxjs/add/operator/do';
    
    @Component({
      selector: 'my-app',
      template: `
        <form novalidate [formGroup]="form">
          <div>
            <select type="text" class="form-control" name="title" formControlName="title">
              <option *ngFor="let title of titles" value="{{title}}">{{title}}</option>
            </select>
          </div>
          <div>
            <input type="text" class="form-control" name="name" formControlName="name">
          </div>
          <fieldset formGroupName="address">
            <legend>Address</legend>
            <input type="text" class="form-control" name="street" formControlName="street">
            <input type="text" class="form-control" name="city" formControlName="city">
          </fieldset>
        </form>
      `,
    })
    export class App implements OnInit {
      private form: FormGroup;
      private titles: string[] =  ['Mr', 'Mrs', 'Ms'];
    
      constructor(private fb: FormBuilder){
    
      }
      ngOnInit() {
        this.form = this.fb.group({
          title: 'Mr',
          name: '',
          address: this.fb.group({
            street: '',
            city: ''
          })
        });
    
        this.form.get('name').valueChanges
          .do(changes => {
            console.log('name has changed:', changes)
            })
          .subscribe();
    
        this.form.get('title').valueChanges.subscribe(
          changes => console.log('title has changed:', changes)
        );
    
        this.form.get('address').valueChanges.subscribe(
          changes => console.log('address has changed:', changes)
        );  
      }
    }
    
    @NgModule({
      imports: [ BrowserModule, FormsModule, ReactiveFormsModule ],
      declarations: [ App ],
      bootstrap: [ App ]
    })
    export class AppModule {}
    

    另一种解决方案是使用“ngModelChange”事件

    在模板中更改此内容:

    <input type="text" class="form-control" (ngModelChange)="doNameChange($event)" name="name" formControlName="name">
    

    在您的组件中处理您的更改事件:

    doNameChange(event: any){
       alert("change")
    }
    
  • 0

    其中一个方法是:

    debounceTime 将在给定的毫秒后进行订阅 . 如果不需要,请忽略 .

    distinctUntilChanged 将仅强制执行实际值更改 .

    this.form.controls['form_control_name']
                .valueChanges
                .debounceTime(MilliSeconds)
                .distinctUntilChanged()
                .subscribe(val => {
    
                  });
    
  • 2

    我也有这个问题 .

    我想在我的情况下做debounceTime,所以它没有解决我的需求 .

    我其实忘了订阅!

    但我能够通过这种方式获得 Value 变化:

    this.form.get('name').valueChanges.forEach(
        (value) => {console.log(value);} )
    

    来自Angular文档中的这里:hero-detail-component.ts

相关问题