如何在 Angular2 中脏检查可迭代组件属性?

2024-05-07

看一下这个简单的 Angular2 组件:

@Component({
  selector: 'status-area',
  directives: [],
  template: require('./status-area.tpl.jade')
})

export class StatusAreaComponent {

  constructor(private _settings: SettingsProvider) {}

  get items() {
     return _.filter(this._settings.features, (feature: any) => {
      return feature.inStatusBar && feature.isEnabled;
    });
  }
}

设置提供者有财产features,由另一个组件(例如 SettingsPanel)修改。该组件仅通过服务链接(无输入参数)。

因此,正如您所看到的,我只需要从 _settings.features 属性中获取已启用并标记为状态栏兼容的功能。

为此,我使用 lodash 方法 find。

然而,正如您可能猜到的,Angular 在开发模式下抛出异常:

检查后表情发生变化

发生这种情况是因为_.filter()每次传递都会返回数组的新实例,但集合是相同的。

我的问题是,你如何解决这种情况?或者可能有另一种解决方案/方法来处理这种情况。

在我看来,如果 angular2 有这样的特殊装饰器,那将非常有用:

@checkIterable()
get items() {
     return _.filter(this._settings.features, (feature: any) => {
      return feature.inStatusBar && feature.isEnabled;
    });
  }

当然,我可以通过使用另一种方法(使用事件和事件侦听器)来解决此问题,但它会产生大量样板代码。

看一下这个例子:

export class StatusAreaComponent implements OnInit, OnDestroy {

  protected _items;
  protected _removeWatcherFn;

  constructor(private settings: SettingsProvider) {}

  ngOnInit() {
    this._items =  this._fetchItems();

    this._removeWatcherFn = this.settings.onChange.bind(() => {
      this._items =  this._fetchItems();
    });
  }

  ngOnDestroy() {
    this._removeWatcherFn();
  }

  _fetchItems() {
    return _.filter(this.settings.features, (feature: any) => {
      return feature.inStatusBar;
    });
  }


  get items() {
    return this._items;
  }
}

这样 Angular 很高兴,但我不高兴。


由于您已经在使用 lodash,您可以使用方便的_.memoize https://lodash.com/docs#memoize方法来缓存过滤结果。它通常用于避免昂贵的计算,但在您的情况下,您可以从其副作用中受益,因为 Angular 不会出现此问题,因为每次检查的过滤数组都是不同的对象。

这是该问题的可能解决方案:

@Component({
  selector: 'status-area',
  directives: [],
  template: require('./status-area.tpl.jade')
})
export class StatusAreaComponent {

  constructor(private _settings: SettingsProvider) {
    this.initFilter();
  }

  initFilter() {

    function filterItems(items) {
      return _.filter(items, (feature: any) => {
        return feature.inStatusBar && feature.isEnabled;
      })
    }

    this.filterFeatures = _.memoize(filterItems, function(items) {
      return filterItems(items).map(item => item.id).join();
    });
  }

  get items() {
    return this.filterFeatures(this._settings.features);
  }

}

Demo: http://plnkr.co/edit/MuYUO3neJdTs0DHluu0S?p=info http://plnkr.co/edit/MuYUO3neJdTs0DHluu0S?p=info

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Angular2 中脏检查可迭代组件属性? 的相关文章

随机推荐