Я новичок в angular и столкнулся с проблемой, когда Angular16 не отображает свойства объекта, определенного во внешнем классе. Посмотрите на следующую иллюстрацию.
Я определил класс следующим образом. Я использую этот класс для хранения данных, которые получаю от серверной части. Эти значения повторно используются в других компонентах.
export class StaticClass {
static dict:{[key: string]: Array<object> } = {
1: [],
2: [
{ id: 1, text: "Hello" },
],
3: [],
}}
Затем я импортирую этот класс, чтобы использовать сохраненные значения.
import { Component } from '@angular/core';
import { StaticClass } from 'src/app/utils/calendarEvents';
@Component({ ..<omitted>.. })
export class SampleViewComponent {
staticClass = StaticClass;
temp = [{ id: 1, text: "Hello" }]
constructor(){
console.info(this.staticClass.dict[2])
console.info(this.temp)
}
}
Здесь оба вывода консоли отображают одно и то же. Однако TS выдает мне ошибку, когда я пытаюсь отобразить значения в staticClass.
<div *ngFor = "let i of this.staticClass.dict[2]">
{{ i.id }}
</div>
Свойство «id» не существует для типа «object».ngtsc(2339)
Но он отлично работает при использовании temp.
<div *ngFor = "let i of this.temp">
{{ i.id }}
</div>
Вопросы:
Привет @YongShun Принято к сведению. Спасибо
Разница между значениями:
в StaticClass
: определяется как тип Array<object>
.
для переменной temp
: определяется как { id: number; text: string; }[]
.
Хотя в целом мы понимаем, что оба они являются массивами объектов, но компилятор обращается с ними по-разному. object
реализует/расширяет интерфейс Object
. Для справки: «любой» или «Объект»
Если вы знаете структуру вашего объекта и она единообразна (одна и та же структура применяется ко всем объектам), вы можете определить тип как:
export class StaticClass {
static dict: { [key: string]: Array<{id: number; text: string}> } = {
1: [],
2: [{ id: 1, text: 'Hello' }],
3: [],
};
}
Или вы можете использовать any
, чтобы компилятор пропускал проверку типов.
export class StaticClass {
static dict: { [key: string]: Array<any> } = {
1: [],
2: [{ id: 1, text: 'Hello' }],
3: [],
};
}
Привет @Ён Шун! Большое спасибо. Это помогло. Поэтому лучше определить тип массива или позволить ему быть любым. Есть ли какой-либо вариант использования, когда полезно определить тип как Array<object>?
Насколько я знаю, тип object
используется при попытке проверить, что значение не является примитивным: typescriptlang.org/docs/handbook/release-notes/…
Попробуйте использовать
!
, чтобы избежать ошибки, не инициированной объектом.
<div *ngFor = "let i of this.temp">
{{ i!.id! }}
</div>
@ Ён Шун уже дал правильный ответ. Несмотря на то, что я настоятельно рекомендую использовать полный набор функций машинописного текста, используя типы/интерфейсы.
Этого можно добиться следующим образом:
статическийкласс.ts
export interface Parent {
[key: string]: Array<Something>;
}
export interface Something {
id: number;
text: string;
additionalInfo?: string; // optional parameter
}
export class StaticClass {
static dict: Parent = {
1: [],
2: [{ id: 1, text: 'Hello' }],
3: [{ id: 5, text: 'asf', additionalInfo: 'great product!' }],
// 4: [{ id: 5, txt: 'asf'}], // ❌ typo in 2nd parameter would throw TS-error
};
Благодаря этому (а) при компиляции могут быть обнаружены ошибки типа (б) какой-то пользователь ваших компонентов знает, какие данные он может ожидать.
мой.компонент.ц
@Component({
/* ... */
templateUrl: `my.component.template.html`,
})
export class App {
dict: Parent = StaticClass.dict; // ✅ dev sees whats going on on first sight
}
мой.компонент.шаблон.html
@for(i of this.dict[2]; track i.id) {
{{ i.id }} <!-- ✅ dev knows id exists without checking StaticClass -->
}
В сообществе Stack Overflow мы не рекомендуем задавать несколько вопросов в одном сообщении, если они не связаны между собой. Таким образом, ваш вопрос 2, в котором спрашивается, как хранить данные в приложении Angular, должен быть в другом сообщении, а не в том же сообщении, что и ваш основной вопрос. Meta.stackoverflow.com/questions/402523/…