Проблема в том, что в качестве входной переменной объект reminders
изначально не определен, пока angular не завершит инициализацию компонента. Смотрите эту строку прямо здесь.
@Input() reminders;
HTML-часть, однако, не ожидает рендеринга и поэтому пытается использовать эту переменную очень рано.
<input name="nameField" class="form-control" [ngModel]="reminders.name">
Поэтому, когда он пытается разрешить модель до того, как в процессе инициализации будет задана входная переменная, он попадает в неопределенную переменную и пытается найти в ней поле name
, которое, конечно, еще не существует.
Существует несколько способов решения этой проблемы.
- присваивает объекту
reminders
значение по умолчанию, возможно, даже пустой объект. Я лично думаю, что таким образом вы жертвуете использованием памяти, чтобы предотвратить ошибки, которые кажутся нечистыми
- используйте оператор elvis в качестве пустой проверки в вашем html:
[ngModel]="reminders?.name"
. Вы должны делать это в каждом поле, которое пытается получить доступ к полю объекта напоминания, в котором может быть много кода в зависимости от вашей формы
- отображает форму только когда объект напоминания наконец установлен. Это легко сделать с помощью простого
*ngIf
на окружающем элементе div или форме: <div class="form-group" *ngIf="reminders">
Возможно, это личный выбор, но для меня последний вариант кажется самым чистым. Нет причин визуализировать ваше представление до того, как необходимые значения существуют, а затем повторно отобразить его, когда они установлены.
Есть еще вопросы по этой теме, например, вы можете проверить этот один прямо здесь.
Надеюсь, это поможет.
EDIT
Итак, я перепроверил ваш код, и хотя ваша функция updateReminder
является отправкой формы, я думаю, что это чистая форма обновления. В этом случае я бы сказал, что вариант 3 должен работать нормально. Angular выполняет аккуратное обнаружение и повторное отображение изменений, поэтому вам, вероятно, следует сначала проверить, правильно ли установлена входная переменная. Если да, angular должен сделать все остальное и перерисовать часть *ngIf
в тот момент, когда он осознает, что объект существует сейчас.
Прежде чем мы проверяем входную переменную, всегда полезно понять, как угловые обрабатывают входные переменные, которые в конце концов сводятся к так называемым Lifecycle Hooks . Одним из специальных крючков является крючок ngOnInit()
. Вот что говорит документация angular о крючке:
Инициализировать директиву / компонент после того, как Angular впервые отобразит привязанные к данным свойства и установит входные свойства директивы / компонента
В основном это означает, что переменные, переносимые в компонент как @Input
, не устанавливаются при создании компонента (код конструктора), но только после его инициализации. Это приводит к некоторой задержке выполнения и в итоге к ошибке, которую вы указали выше.
Чтобы проверить, правильно ли установлена входная переменная, мы можем просто зарегистрировать ее на консоли внутри ngOnInit()
.
ngOnInit() {
console.log(this.reminders);
}
Для сравнения, если вы сделаете это в конструкторе, вы увидите, что он все еще пуст на данный момент.
constructor(private reminderService:ReminderService) {
// should be undefined at this point
console.log(this.reminders);
}
Таким образом, если переменная напоминаний регистрируется из ngOnInit
, подход *ngIf
должен работать нормально.