订阅Angular 2中组件属性的更改以进行去抖动的自动保存? [英] Subscribe to changes on property of component in Angular 2 for debounced auto saving?

查看:68
本文介绍了订阅Angular 2中组件属性的更改以进行去抖动的自动保存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有以下Angular 2组件,其中foo是未绑定到表单且不来自Input()的对象:

Say I have the following Angular 2 component, where foo is an object not bound to a form, and not coming from an Input():

@Component({
    selector: 'foo',
    templateUrl: '/angular/views/foo.template.html',
    directives: [ContentEditableDirective, ROUTER_DIRECTIVES],
    providers: [FooService]
})
export class FooComponent implements OnInit {
    public foo: Foo = new Foo();

    constructor(
        private fooService: FooService,
        private route : ActivatedRoute,
        private router : Router) {}

    ngOnInit() {
        let id = +this.route.snapshot.params['id'];
        this.fooService.getFoo(id).subscribe(
            foo => {
                this.foo = foo;

                // I have this.foo, we should watch for changes here.

                Observable. // ???
                    .debounceTime(1000)
                    .subscribe(input => fooService.autoSave(this.foo));
            },
            error => console.log(error)
        );
    }
}

如何订阅对Foo对象的更改,并将其发送到我的服务器?

How can I subscribe to changes to the Foo object, and send it up to my server?

到目前为止,我看到的每个示例都涉及使fooInput()脱离或绑定到表单.我只想看着一个普通的旧Javascript对象进行更改并对此做出反应.

Every example I have seen so far involves either having foo come off of an Input(), or being bound to a form. I just want to watch a plain old Javascript object for changes and react to that.

我再次尝试过,并且能够对组件primitive 属性进行反跳rel ="noreferrer">此处.

I have tried once again, and have been able to debounce an internal primitive property on a component here.

但是,我无法使用具有其自身属性的复杂对象(此处);因为提供的plnkr中的setter在更新foo对象的属性时不会被ngModel调用.

But, I have been unable to make this work with a complex object that has properties of its own (here); as the setter in the provided plnkr is not called by ngModel when it updates the property of the foo object.

正确的答案将演示如何使用复杂的对象.

A correct answer will demonstrate this working with a complex object.

我相信我可以使用复杂的对象;但必须确保该对象是不可变的,并且您必须为每个属性设置setter,这有点令人失望.似乎还需要将[(ngModel)]拆分为[ngModel](ngModelChange),以便您可以指定自定义设置程序逻辑.

I believe I have it working with a complex object; but one must ensure the object is immutable and that you have setters for each property, which is kind of a letdown. It also appears to require the splitting of [(ngModel)] into [ngModel] and (ngModelChange) so you can specify custom setter logic.

从理论上讲,您可以将功能抽象为状态服务,但是我想看看是否可以进一步减少样板的数量.每次您想要状态更改时创建新对象都会让人感到沮丧.

You could theoretically abstract the functionality to a state service, but I'd like to see if the amount of boilerplate can be stripped down further. Creating new objects each time you would like a state change is kind of frustrating.

推荐答案

为了简单起见,我似乎已部分解决了此问题.复杂的对象.如果您不需要整个变更检测器,则只需使用以下方法即可轻松实现:

I appear to have partially solved this for simple & complex objects. If one has no need for an entire change detector, you can implement this easily with just:

  • 主题和组件中的可观察对象.
  • 组件上被跟踪属性的获取器和设置器.

下面是一个非常简单的示例,说明了如何完成此操作.

Below is a very minimal example of how one could accomplish this.

import {Component} from '@angular/core'
import {Subject} from 'rxjs/Rx';

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <input type="text" [(ngModel)]="foo"  />
      <div>current Foo: {{ foo }}</div>
      <div>debounced Foo: {{ debouncedFoo }}</div>
    </div>
  `,
  directives: []
})
export class App {
  private _foo: any;
  debouncedFoo: any;
  fooSubject : Subject<any> = new Subject<any>(this._foo);
  fooStream : Observable<any> = this.fooSubject.asObservable();

  get foo() {
      return this._foo;
  });

  set foo(value:any) {
    this._foo = value;
    this.fooSubject.next(value);
  });

  constructor() {
    // Manipulate your subscription stream here
    this.subscription = this.fooStream
      .debounceTime(2000)
      .subscribe(
        value => {
          this.debouncedFoo = value;
      });
  }
}

示例

http://plnkr.co/edit/HMJz6UWeZIBovMkXlR01?p=preview

当然,实际上,该组件应该不了解主题或不可观察,因此请根据需要将其提取到服务中.

Of course, realistically the component should have no knowledge of the subject or observable, so extract them to a service as you please.

此示例仅适用于基元.如果您希望它与对象一起使用,则需要为每个属性自定义设置逻辑,并记住每次更改该对象的属性时都要创建新对象.

This example only works with primitives. If you would like it to work with objects, you need custom setter logic for each property, and remember to create new objects each time you alter a property of that object.

这篇关于订阅Angular 2中组件属性的更改以进行去抖动的自动保存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆