使用方法将来自后端的 JSON 个对象键入为正确的打字稿 类
Typing JSON objects coming from the backend as proper typescript classes with methods
我正在尝试将从后端返回的 json 映射到 angular 端的正确打字稿 classes。
这是我的后端代码:
findMessagesWithOtherUserAccount(otherId:Number):Observable<Message[]> {
return this.http.get('/api/message/find-messages-with-other-useraccount/' + otherId)
.map(this.extractMessages);
}
private extractMessages(res:Response) {
let body = res.json();
return body || {};
}
注意 Message
的 Observable
。这里 Message
是我需要的类型,因为我在 class 中添加了如下业务逻辑:
import {UserAccount} from "../useraccount/useraccount.model";
export class Message {
constructor(id:number,
sender:UserAccount,
recipient:UserAccount,
sendDate:Date,
messageRead:boolean,
text:string) {
this.id = id;
this.sender = sender;
this.recipient = recipient;
this.sendDate = sendDate;
this.messageRead = messageRead;
this.text = text;
}
id:number;
sender:UserAccount;
recipient:UserAccount;
sendDate:Date;
messageRead:boolean;
text:string;
getCounterparty(user:UserAccount):UserAccount {
if (!this.sender) return null;
return (user.id !== this.sender.id) ? this.sender : this.recipient;
}
isSender(user:UserAccount):boolean {
return user.id === this.sender.id;
}
isRecipient(user:UserAccount):boolean {
return user.id === this.recipient.id;
}
isNew(user:UserAccount):boolean {
return !this.messageRead && this.isRecipient(user);
}
}
我尝试从组件中引用 isRecipient
方法:
getSenderFirstName(message:Message):string {
if (message.isRecipient(this.currentUserAccount)) {
return this.otherUserAccount.firstName;
}
return 'Moi';//FIXME: i18n/translate
}
但是,我得到这个错误:
browser_adapter.js:81 TypeError: message.isRecipient is not a function
at MessageConversationComponent.getSenderFirstName (message-conversation.component.js:50)
表示消息未键入(普通 js 对象除外)...
这是完整的组件:
export class MessageConversationComponent implements OnInit {
messagesWithOtherUserAccount:Message[];
currentUserAccount:UserAccount;
otherUserAccount:UserAccount;
constructor(private messageService:MessageService,
private userAccountService:UserAccountService,
private routeSegment:RouteSegment) {
}
ngOnInit() {
this.messageService.findMessagesWithOtherUserAccount(2)
.subscribe(param=>this.messagesWithOtherUserAccount = param);
this.userAccountService.retrieveOtherUserAccount(2)
.subscribe(param=> this.otherUserAccount = param);
this.userAccountService.currentUserAccount$.subscribe(param=>this.currentUserAccount = param);
}
getSenderFirstName(message:Message):string {
if (message.isRecipient(this.currentUserAccount)) {
return this.otherUserAccount.firstName;
}
return 'Moi';//FIXME: i18n/translate
}
}
和模板:
<div *ngFor="let message of messagesWithOtherUserAccount" class="media col-xs-12">
<div class="media-body Lui" ng-class="getMessageClasses(message)">
<div class="media-heading">
{{getSenderFirstName(message)}} <small><span am-time-ago="message.sendDate"></span></small>
</div>
<p class="message-text">{{message.text}}</p>
</div>
</div>
您不能只将 JSON 转换为 class 实例。如果你真的需要一个 class 的方法,你需要用 new SomeClass()
创建它,比如:
private extractMessages(res:Response) {
let body = res.json();
if(body) {
return new Message(
body.id,
new UserAccount(body.sender),
new UserAccount(body.recipient),
new Date(body.sendDate),
body.messageRead,
body.text);
} else {
return new Message(
}
}
如果您只想对属性进行类型化访问,您可以使用接口而不是 class 并强制转换为该接口以获取自动完成和静态类型检查。
我正在尝试将从后端返回的 json 映射到 angular 端的正确打字稿 classes。
这是我的后端代码:
findMessagesWithOtherUserAccount(otherId:Number):Observable<Message[]> {
return this.http.get('/api/message/find-messages-with-other-useraccount/' + otherId)
.map(this.extractMessages);
}
private extractMessages(res:Response) {
let body = res.json();
return body || {};
}
注意 Message
的 Observable
。这里 Message
是我需要的类型,因为我在 class 中添加了如下业务逻辑:
import {UserAccount} from "../useraccount/useraccount.model";
export class Message {
constructor(id:number,
sender:UserAccount,
recipient:UserAccount,
sendDate:Date,
messageRead:boolean,
text:string) {
this.id = id;
this.sender = sender;
this.recipient = recipient;
this.sendDate = sendDate;
this.messageRead = messageRead;
this.text = text;
}
id:number;
sender:UserAccount;
recipient:UserAccount;
sendDate:Date;
messageRead:boolean;
text:string;
getCounterparty(user:UserAccount):UserAccount {
if (!this.sender) return null;
return (user.id !== this.sender.id) ? this.sender : this.recipient;
}
isSender(user:UserAccount):boolean {
return user.id === this.sender.id;
}
isRecipient(user:UserAccount):boolean {
return user.id === this.recipient.id;
}
isNew(user:UserAccount):boolean {
return !this.messageRead && this.isRecipient(user);
}
}
我尝试从组件中引用 isRecipient
方法:
getSenderFirstName(message:Message):string {
if (message.isRecipient(this.currentUserAccount)) {
return this.otherUserAccount.firstName;
}
return 'Moi';//FIXME: i18n/translate
}
但是,我得到这个错误:
browser_adapter.js:81 TypeError: message.isRecipient is not a function
at MessageConversationComponent.getSenderFirstName (message-conversation.component.js:50)
表示消息未键入(普通 js 对象除外)...
这是完整的组件:
export class MessageConversationComponent implements OnInit {
messagesWithOtherUserAccount:Message[];
currentUserAccount:UserAccount;
otherUserAccount:UserAccount;
constructor(private messageService:MessageService,
private userAccountService:UserAccountService,
private routeSegment:RouteSegment) {
}
ngOnInit() {
this.messageService.findMessagesWithOtherUserAccount(2)
.subscribe(param=>this.messagesWithOtherUserAccount = param);
this.userAccountService.retrieveOtherUserAccount(2)
.subscribe(param=> this.otherUserAccount = param);
this.userAccountService.currentUserAccount$.subscribe(param=>this.currentUserAccount = param);
}
getSenderFirstName(message:Message):string {
if (message.isRecipient(this.currentUserAccount)) {
return this.otherUserAccount.firstName;
}
return 'Moi';//FIXME: i18n/translate
}
}
和模板:
<div *ngFor="let message of messagesWithOtherUserAccount" class="media col-xs-12">
<div class="media-body Lui" ng-class="getMessageClasses(message)">
<div class="media-heading">
{{getSenderFirstName(message)}} <small><span am-time-ago="message.sendDate"></span></small>
</div>
<p class="message-text">{{message.text}}</p>
</div>
</div>
您不能只将 JSON 转换为 class 实例。如果你真的需要一个 class 的方法,你需要用 new SomeClass()
创建它,比如:
private extractMessages(res:Response) {
let body = res.json();
if(body) {
return new Message(
body.id,
new UserAccount(body.sender),
new UserAccount(body.recipient),
new Date(body.sendDate),
body.messageRead,
body.text);
} else {
return new Message(
}
}
如果您只想对属性进行类型化访问,您可以使用接口而不是 class 并强制转换为该接口以获取自动完成和静态类型检查。