0

Angular 1 にあった$watch機能が Angular 2 には欠けていると感じています。

OnChangesDoCheck置き換えることになっ$watchていますが、どちらも使用して目的の結果を得ることができませんでした。OnChangesオブジェクトをリッスンできないため、このシナリオでは役に立ちDoCheckません。ジョブを実行している間、変更が発生するとすぐにバナナになるように見えるため、大きな遅延が発生します。

ここでは、一連のチェックボックスを持つコンポーネントを用意しています。各チェックボックスの切り替えにより、デフォルトの機能ではなく、値が配列に追加されますtrue/false

このコンポーネントで監視する必要があるisDisabledのは、チェックボックスの状態です。そのため、状態が変化するたびに、のisChecked状態を更新する必要がありcheckboxます。

私が言ったように、それは機能しますが、チェックボックスが5つしかないにもかかわらず、チェックボックスの切り替えごとに2〜3秒の遅延があります. チェックボックスを切り替えるたびにループを実行するのではなく、isDisabledチェックボックスの状態が変化した場合にのみループを実行することをお勧めします。

編集:Observableここで仕事をすることができると言われましたが、このようなオブジェクトの配列に適用されている例は見つかりません。next()また、送信される配列への外部の変更をリッスンする必要があるため、メソッドを手動で呼び出さずにトリガーする必要もあります。

EDIT 2:ラグを表示しないplunkrを作成しました. ただし、plunkr は、関数console.log(true)内にa を配置し、何度も実行されるため、何か問題があるように見えることを明確に示しています。ngDoCheck()これは意図したものではありません。もしそうなら、それは本当に奇妙です。

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 に答える