Angular прослушивает изменение значения числового свойства (НЕ @Input) с помощью - ngDoCheck?

У меня есть массив ставок FormGroup, а именно ratesMainArray является @Input от родителя к моему дочернему компоненту. Я фильтрую его в ngOnChanges по значению ключа special или normal каждый раз, когда его длина в родительском компоненте изменяется, и сохраняю значение length отфильтрованного массива в двух локальных свойствах, specialRates и normalRates, которые, конечно, имеют тип number. Мне нужно слушать изменения этого значения длины, но ngOnChanges реагирует только на изменения родительского массива. Я начал использовать ngDoCheck, который фактически обнаруживает изменения значений отфильтрованных массивов, но я получаю сообщение об ошибке Error trying to diff '2'. Only maps and objects are allowed, когда пытаюсь отреагировать на длину отфильтрованного массива.

Это упрощенная версия кода:

...
@Input() ratesMainArray: FormGroup[];
specialRates: number;
normalRates: number;
differ: any;

constructor(private differs: KeyValueDiffers) {
    this.differ = differs.find({}).create();
  }

ngDoCheck() {
    const changes = this.differ.diff(this.specialRates);
      if (changes) {
         changes.forEachAddedItem(r => console.log('added ' + r.currentValue));
                   }
}

async ngOnChanges(changes: SimpleChanges) {

    if ((this.ratesMainArray && this.ratesMainArray.length) 
         && (changes && changes.ratesMainArray && changes.ratesMainArray.currentValue.length)) {

this.specialRates= this.ratesMainArray.filter(t => t.controls.isSpecialRate.value === true).length;
this.normalRates= this.ratesMainArray.filter(t => t.controls.isSpecialRate.value === false).length;

}

// ideally, I would like to do something like this:
// if (this.specialRates.valueChanges or changes.specialRates.currentValue) {
// do somthing
// } else {
// do something else
// }

}

Мне не обязательно использовать ngDoCheck, но поскольку он обнаруживал изменение отфильтрованного массива, я подумал, что это правильный путь. Просто для ясности я также безуспешно пытался использовать private cd: ChangeDetectorRef и this.cd.detectChanges();, прежде чем попробовать ngDoCheck.

Спасибо за помощь!!


person mike87    schedule 13.11.2019    source источник


Ответы (1)


Вы можете использовать set для анализа данных, которые вы получаете в @Input().

specialRates: number;
normalRates: number;
differ: any;
private _ratesMainArray: FormGroup[];
get ratesMainArray(): FormGroup[] {
   return this._ratesMainArray;
}
@Input() set ratesMainArray(value: FormGroup[]){
    if(value) {
      this._ratesMainArray = value;
this.specialRates= this.ratesMainArray.filter(t => t.controls.isSpecialRate.value === true).length;
this.normalRates= this.ratesMainArray.filter(t => t.controls.isSpecialRate.value === false).length;
    }
}

constructor(private differs: KeyValueDiffers) {
   this.differ = differs.find({}).create();
}

Здесь у вас есть еще один пример получения/установки в @Input(): Angular2 @Input в свойство с помощью get/set

person German Quinteros    schedule 13.11.2019
comment
Привет, и спасибо за помощь. Я отредактировал свой код с помощью set и get, теперь я выполняю фильтрацию в @Input(), как вы указали, но все же я не могу обнаружить их изменения в ngOnChanges или ngDoCheck. Я имею в виду, я должен? - person mike87; 13.11.2019
comment
Нет, теперь каждый раз, когда @Input() изменяется, у вас появляются новые значения для ваших свойств. Я только что обновил свой ответ - person German Quinteros; 13.11.2019
comment
Я все еще вижу только simpleChanges, связанный с длиной моего ratesMainArray, к сожалению... и ngDoCheck показывает то же самое [ object Object ]. - person mike87; 13.11.2019