Будет ли использование метода Angular Reactive Forms .get () в шаблоне вызывать ненужные вызовы методов, таких как метод компонента? - PullRequest
1 голос
/ 27 мая 2020

Я знаю, что если я использую вызов метода в шаблоне, он будет выполняться снова и снова (не идеально). Я решил это, используя комбинацию чистых каналов и мемоизированных методов. Но я также использую реактивные формы и в своем шаблоне использую значение myFormGroup.get ('myFormControl'). Для получения значений. Будет ли это тоже выполняться многократно, как метод в моем компоненте, или в Angular есть стратегия, предотвращающая это? Пример использования - использование * ngIf и условное выражение, основанное на значении формы.

Кроме того, в настоящее время я не испытываю никакого снижения производительности, но я хотел бы реализовать это наилучшим образом, прежде чем слишком далеко зашел с этим приложением (и мне просто любопытно).

Я могу легко обновить его, чтобы напрямую ссылаться на свойства объекта формы, я просто предпочитаю синтаксис вызова метода. Любая информация будет полезна, спасибо!

1 Ответ

0 голосов
/ 27 мая 2020

Вот что происходит, когда вы вызываете AbstractControl.get(...):

get(path: Array<string|number>|string): AbstractControl|null {
  return _find(this, path, '.');
}

Source .

А функция _find выглядит так:

function _find(control: AbstractControl, path: Array<string|number>|string, delimiter: string) {
  if (path == null) return null;

  if (!Array.isArray(path)) {
    path = path.split(delimiter);
  }
  if (Array.isArray(path) && path.length === 0) return null;

  // Not using Array.reduce here due to a Chrome 80 bug
  // https://bugs.chromium.org/p/chromium/issues/detail?id=1049982
  let controlToFind: AbstractControl|null = control;
  path.forEach((name: string|number) => {
    if (controlToFind instanceof FormGroup) {
      controlToFind = controlToFind.controls.hasOwnProperty(name as string) ?
          controlToFind.controls[name] :
          null;
    } else if (controlToFind instanceof FormArray) {
      controlToFind = controlToFind.at(<number>name) || null;
    } else {
      controlToFind = null;
    }
  });
  return controlToFind;
}

Источник .

Как вы заметили, вы можете получить потомков, которые находятся глубже в дереве управления формой.

Например:

form.get('a.b.c')

// Or

form.get(['a', 'b', 'c'])

Весь этот logi c вызывает итерацию , потому что он перебирает каждый элемент из path.


Будет ли это тоже выполняться повторно как метод в моем компоненте

Я бы сказал, что будет.

Я создал демонстрацию StackBlitz , чтобы проиллюстрировать это:

@Component({
  selector: 'my-app',
  template: `
    <form [formGroup]="form">
      <input formControlName="name" type="text">  
    </form>

    <hr>

    <p>
      Getter value: {{ name.value }}
    </p>
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  form: FormGroup;
  name2: FormControl

  get name (): FormControl {
    console.log('getter invoked!')

    return this.form.get('name') as FormControl;
  }

  constructor (private fb: FormBuilder) { }

  ngOnInit () {
    this.form = this.fb.group({ name: '' });

    this.name2 = this.form.get('name') as FormControl;
  }
}

Если вы используете getter, вы должны увидеть getter invoked!, зарегистрированное дважды для каждого символа, который вы вводите во вводе (и метод get, вызываемый также несколько раз).

Если вы используете {{ form.get('name').value }}, метод AbstractControl.get будет вызываться несколько раз, более ожидаемого .

Вы можете проверить это, открыв инструменты разработчика и набрав forms.umd.js и поместив log breakpoint в эту строку path.forEach(function (name) {...} внутри тела функции _find.

И если вы используете this.name2 = this.form.get('name') as FormControl;, вы не должны видеть ничего записанного при вводе.

На мой взгляд, менее вероятно, что производительность visible снизится, если вы используете getter или .get(), но я бы go с третьим подходом, создавая отдельный property для элемента управления, который я буду использовать в представлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...