#angular #typescript
#angular #typescript
Вопрос:
Я столкнулся со странной ошибкой в Angular 2. У меня есть два похожих компонента с похожими шаблонами и похожими сервисами. Вот основы того, как они работают:
Компонент:
theData: any;
constructor(private _theService: TheService) {}
ngOnInit() {
this._theService.getData()
.subscribe(data => {
this.theData = data;
});
}
Обслуживание:
private _url = "http://url.net/api/Data";
constructor(private _http: Http) {
}
getData() {
return this._http.get(this._url)
.map(res => res.json());
}
это возвращает массив объектов, например:
[
{name: "Name 1"},
{name: "Name 2"}
]
и шаблон отображает их следующим образом:
<div *ngFor="let item of theData">{{ item.name }}</div>
Затем вы можете щелкнуть элемент, где вы попадаете на страницу, которая следует той же стратегии, что и выше, за исключением того, что service / api возвращает только один объект, а шаблон не использует *ngFor, потому что для отображения требуется только один элемент.
Итак, это выглядит так:
theItem = {name: "Name 1"} // what the service returns
<div>{{ theItem.name }}</div>
Все отлично работает при отображении всех элементов, но когда я нажимаю на отдельные элементы, OnInit вызывается дважды, и я получаю сообщение об ошибке в platform-browser.umd.js что на самом деле является ошибкой в шаблоне, потому что в нем говорится, что он не может прочитать свойство name
undefined
(которое является элементом).
Я решил эту проблему, изменив шаблон для отдельных элементов на:
<div>{{ theItem?.name }}</div>
Сначала я подумал, что проблема заключалась в том, что шаблон отображался до загрузки данных из службы, поэтому добавление ?
исправило это. Но разве шаблон не должен загружаться ПОСЛЕ завершения ngOnInit? Мой вопрос в том, почему добавление ?
исправило эту проблему, хотя мне это не нужно в первом шаблоне при загрузке всех элементов?
Спасибо.
Ответ №1:
Поскольку get
он асинхронный, он фактически начинает отображать шаблон до загрузки данных. Он завершит вызов службы и не будет ждать, он продолжит обработку. Добавление ?
позволяет ему быть undefined
, а затем отображать соответствующим образом после загрузки данных.
Комментарии:
1. Хорошо, значит, единственная причина, по которой это работает в первом сценарии, заключается в том, что служба возвращает данные достаточно быстро, а шаблон еще не был отрисован?
2. или
*ngFor
обрабатывает его как неопределенный, тогда как прямая ссылка на объект этого не делает. Честно говоря, я не уверен, я никогда не углублялся в этот сценарий3. Да, мне было интересно, было ли это *ngFor для его обработки, и я думаю, что это так. Я сообщу, если найду что-нибудь еще по этому поводу. Спасибо!
4. Получил ту же проблему слово в слово. Другой способ решить эту проблему — использовать
*ngIf="theItem"
в корневом узле шаблона. Это позволяет избежать использования?
при каждой привязке. Мои предыдущие шаблоны работали нормально, потому что они уже его использовали. Кроме того, обратите внимание, что я столкнулся с этой проблемой, потому что мой компонент использует параметры маршрута, которые извлекаются изActivatedRoute
черезObservable
, поэтому, я думаю, почему «задержка».