我正在学习离子和角质。在此应用中,我正在使用以下课程
model.ts
export class Feed {
constructor(
public type: string,
public object: ReactionObject | ObituaryObject
) {}
}
export class ReactionObject {
constructor(
public actionId: string,
public obituaryId: string,
public categoryId: string,
public timestamp: string,
public userName: string,
public userPhoto: string,
public deceasedName: string,
public thanked: string,
public community: CommunityObject,
public obituarySponsorId: string
) {}
}
export class ObituaryObject {
constructor(
public categoryId: string,
public deathDay: string,
public funeral: FuneralObject,
public name: string,
public obituaryId: number,
public photo: string
) {}
}
types.ts
export interface ApiData {
error: string;
session_id: string;
data: any;
message?: string;
}
export interface FeedData extends ApiData {
type: string;
object: ReactionData | SingleObituaryData;
}
export interface ReactionData extends ApiData {
actionId: string;
obituaryId: string;
categoryId: string;
timestamp: string;
userName: string;
userPhoto: string;
deceasedName: string;
thanked: string;
community: CommunityData;
obituarySponsorId: string;
}
export interface SingleObituaryData extends ApiData {
categoryId: string;
deathDay: string;
funeral: FuneralData;
name: string;
obituaryId: number;
photo: string;
}
feed.service.ts
export class FeedService {
private _feed = new BehaviorSubject<Feed[]>([]);
get feed() {
return this._feed.asObservable();
}
constructor(private authService: AuthService, private http: HttpClient) {}
getFeed(pageNumber: number) {
return this.authService.userToken.pipe(
take(1),
switchMap((token) => {
return this.http.get<FeedData>(
`${environment.apiURL}getFeed&token=${token}&page=${pageNumber}`
);
}),
map((resData) => {
resData = resData.data.items;
console.log(resData);
const feed = [];
for (const key in resData) {
if (resData.hasOwnProperty(key)) {
feed.push(
new Feed(
resData[key].type,
new ReactionObject(
resData[key].object.actionId,
resData[key].object.obituaryId,
resData[key].object.categoryId,
resData[key].object.timestamp,
resData[key].object.userName,
resData[key].object.userPhoto,
resData[key].object.deceasedName,
resData[key].object.thanked,
resData[key].object.community,
resData[key].object.obituarySponsorId,
)
)
);
}
}
return feed;
}),
tap((feed) => {
this._feed.next(feed);
})
);
}
}
updates.component.html
<p class="ion-text-center" *ngIf="!isLoading && loadedFeed.length <= 0">
No updates found
</p>
<ion-list *ngIf="isLoading" class="ion-no-padding">
<ion-item *ngFor="let i of Arr(num).fill(1)">
<ion-avatar slot="start">
<ion-skeleton-text animated></ion-skeleton-text>
</ion-avatar>
<ion-label>
<p>
<ion-skeleton-text animated style="width: 80%;"></ion-skeleton-text>
</p>
</ion-label>
</ion-item>
</ion-list>
<ion-list *ngIf="!isLoading && loadedFeed.length > 0" class="ion-no-padding">
<ion-item *ngFor="let feed of loadedFeed">
<ng-container
*ngIf="
feed.type === 'candle' ||
feed.type === 'flower' ||
feed.type === 'comment'
"
>
<ion-avatar slot="start">
<img src="../../../assets/img/{{ feed.type }}-icon.svg" />
</ion-avatar>
<ion-label>
{{ feed.object.userName }} // issue here
<ng-container *ngIf="feed.type === 'candle'">
lit a candle on
</ng-container>
<ng-container *ngIf="feed.type === 'flower'">
placed a flower on
</ng-container>
<ng-container *ngIf="feed.type === 'comment'">
wrote a message on
</ng-container>
</ion-label>
</ng-container>
</ion-item>
</ion-list>
我从VS代码中收到错误:Identifier 'userName' is not defined. 'ReactionObject | ObituaryObject' does not contain such a member
但是,这仍然可以正确显示数据,而且IntelliSense仅显示两个选项: categoryId 和 obituaryId 这两个类都通用。将ObituaryObject
替换为any
可清除错误
我为什么会收到此错误的任何想法?
谢谢
答案 0 :(得分:0)
我认为这是因为在您的 Feed 类中,您有一个字段 object ,其中包含两个使用Union Type的可用提示。 ObituaryObject 没有字段userName。
我建议避免使用TypeScript inheritance使用UnionType来支持父对象。
通过这种方式的代码也将更加清晰。
您的模型将变为:
export class GenObject {
constructor(
public obituaryId: number,
public categoryId: string
) {
}
}
export class Feed {
constructor(
public type: string,
public object: GenObject
) {
}
}
export class ReactionObject extends GenObject {
constructor(
public actionId: string,
public userName: string,
public obituaryId: number,
public categoryId: string
) {
super(obituaryId, categoryId);
}
}
export class ObituaryObject extends GenObject {
constructor(
public deathDay: string,
public name: string,
public obituaryId: number,
public categoryId: string
) {
super(obituaryId, categoryId);
}
}
接下来,当从视图访问该字段时,将检查强制为这样的特定类:
{{ getReaction(obituaryObject.object).username }}
具有如下定义的方法:
getReaction(object: GenObject) {
if (object instanceof ReactionObject) {
return object as ReactionObject;
}
}
答案 1 :(得分:0)
public object: ReactionObject | ObituaryObject
这定义了object
可以是ReactionObject
或ObituaryObject
类型的
{{ feed.object.userName }} // issue here
将其更改为:
{{ (feed.object as ReactionObject).userName }} // issue should be resolved.
或
{{ (<ReactionObject>feed.object).userName }} // issue should be resolved.
还要在{updates.component.ts
中添加ReactionObject
的导入
import { ReactionObject } from './model.ts' // check the path for model.ts
更新:
在updates.components.ts
中,添加了一个吸气剂
get feedObjectUserName() {
return ( <RectionObject> feed.object).userName
}
并在updates.component.html
中更改为
{{ feedObjectUserName }}
希望有帮助!