0

我觉得 Angular 2 中缺少 Angular 1 的一些东西,其中之一就是$watch功能。

OnChanges并且DoCheck应该替换,$watch但我无法使用其中任何一个来获得所需的结果。OnChanges无法收听对象,因此在这种情况下没有用,并且在DoCheck完成这项工作时,它会导致巨大的延迟,因为一旦发生更改,它似乎就会变得很糟糕。

在这里,我有一个包含一堆复选框的组件,每个复选框切换都会导致将一个值添加到数组中,而不是默认true/false功能。

在这个组件中我需要注意的是复选框的状态isDisabled,所以每次它发生变化时我都需要更新.isCheckedcheckbox

就像我说的,它可以工作,但每个复选框切换都有 2-3 秒的延迟,尽管只有 5 个复选框。最好我不希望每次切换复选框时都运行循环,而是仅在isDisabled复选框的状态发生变化时运行。

编辑:有人告诉Observable我可以在这里完成这项工作,但我找不到任何将其应用于此类对象数组的示例。它还需要在不next()手动调用其方法的情况下触发,因为它必须侦听正在发送的数组的外部更改。

编辑 2:我创建了一个不显示滞后的 plunkr,可能是因为在我的应用程序中我还有其他可能对延迟产生影响的东西。但是,plunkr 清楚地表明似乎有问题,因为我console.log(true)ngDoCheck()函数中放置了 a 并且它运行了很多次。这不是故意的,如果是的话,那真的很奇怪。

这是 plunkr:https ://plnkr.co/edit/dJVnqbrredDyWTXNDzDK?p=preview

我怎样才能做到这一点?

export class FormCheckboxMultipleComponent implements OnInit, DoCheck {
  @Input() model: Array<any>;
  @Output('modelChange') onModelChange: EventEmitter<any> = new EventEmitter();
  @Output() callback: EventEmitter<any> = new EventEmitter();

  constructor(private _globals: GlobalVariablesService) {
    this.ns = _globals.ns;
  }

  ngOnInit() {
    this.model = this.model || [];
  }

  ngDoCheck() {

    for (let checkbox of this.checkboxes) {

      if (checkbox.isDisabled) {
        this.untoggle(checkbox);
      }
    }
  }

  findIndex(checkbox) {

    return this.model.reduce(function(cur, val, index) {

      if (val.name === checkbox.name && cur === -1) {
        return index;
      }

      return cur;
    }, -1);
  }

  addToModel(checkbox) {
    this.model.push(checkbox);
  }

  removeFromModel(i) {
    this.model.splice(i, 1);
  }

  toggle(checkbox) {

    if (checkbox.isDisabled) {
      return false;
    }

    let existingIndex = this.findIndex(checkbox);

    if (existingIndex === -1) {
      this.addToModel(checkbox);
    }
    else {
      this.removeFromModel(existingIndex);
    }

    checkbox.isChecked = !checkbox.isChecked;

    this.onModelChange.emit(this.model);

    this.callback ? this.callback.emit() : false;
  }

  untoggle(checkbox) {

    let existingIndex = this.findIndex(checkbox);

    this.removeFromModel(existingIndex);

    checkbox.isChecked = false;

    this.onModelChange.emit(this.model);
  }
}
4

1 回答 1

1

这是由this.onModelChange.emit(this.model);in this.untoggle(checkbox)in引起的ngDoCheck。这是一个完美的无限循环。this.onModelChange.emit(this.model);导致更改检测并因此ngDoCheck()运行并且循环再次开始。

确保变更检测不会导致变更检测。ngDoCheck由更改检测调用,并且不能调用另一个更改检测,否则您将获得无限循环。

普朗克

于 2016-06-08T16:24:44.957 回答