簡體   English   中英

根據 Typescript Angular 中的類型為類實例屬性分配一個值

[英]Assign class instance property a value based on its type in Typescript Angular

我不知道這在 Typescript 中是否允許,但我正在一個 Angular 7 項目中工作,我想實例化一個Page類來填充他從 DB 對象的所有屬性。 這些是我的課程:

export class User {
    id: number;
    name: string;
    created_at: string;

    constructor(obj?: any) {
        Object.assign(this, obj);
    }

    getName(): string {
        return this.name;
    }
}

export class Page {
    id: number;
    title: string;
    author: User;


    constructor(obj?: any) {
        Object.assign(this, obj);
    }

    showTitle(): string {
        return this.title;
    }
}

這是我檢索數據的服務方法的示例:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { Page } from '../models/page';

@Injectable()
export class PageService {

    constructor(httpClient: HttpClient) {}

    getPage(id: number): Observable<Page> {
        return this.httpClient
                   .get<Page>('http://<my-server-ip>:<port>/api/pages')
                   .pipe(
                       map((page: Page) => {
                           console.log('retrieved', page);
                           return new Page(page);
                       })
                   );
    }
}

這是我的組件中此函數調用的示例

export class MyCustomComponent implements OnInit {

    constructor(pageService: PageService) {}

    ngOnInit() {
        this.pageService.getPage()
            .subscribe((page: Page) => {
                console.log(page.showTitle());
            });
    }
}

此示例有效,但是當我想訪問User方法時,例如:

console.log(page.author.getName());

我無權訪問它們,因為它不是User類的實例化。

如果我不將頁面類的新實例作為可觀察對象返回, Page也會發生同樣的情況,這就是我在檢索數據后使用return new Page(page)的原因。

問題是我想讓我的構造函數盡可能通用,所以創建一個構造函數來手動分配值(例如: this.author = new User(obj.author); )不是一個有效的解決方法,因為我想在每個模型中實現它或創建一個GenericModel然后擴展我的所有模型。

有沒有辦法在實例化類中根據其類型填充具有定義類型的屬性?

這是我到目前為止嘗試過的,但它不起作用:

export class Page {
    // ...
    constructor(obj?: any) {
        Object.keys(obj).forEach((key: string, index: number) => {
            if (typeof(obj[key]) === 'object' && obj[key] !== null) {
                this[key] = new (this[key].constructor)(obj[key]);
            } else {
                this[key] = obj[key]
            }
        });
    }
}
ERROR TypeError: Cannot read property 'author' of null
ERROR TypeError: Cannot read property 'constructor' of undefined

我知道在調用構造函數時this是 null,但我找不到另一種方法來用new實例填充author屬性以訪問方法。 此外,如果我得到一個標准/默認對象,如{ ... }if將觸發並且可能也會拋出錯誤,因為它沒有構造函數。

你可以像這樣使用Object.assign

getPage(id: number): Observable<Page> {
    return this.httpClient
               .get<Page>('http://<my-server-ip>:<port>/api/pages')
               .pipe(
                   map((page: Page) => {
                       console.log('retrieved', page);
                       return Object.assign(new Page(), page);
                   })
               );
}

此代碼創建一個新的 Page 實例,然后從返回的響應(本例中為page )復制所有屬性。

然后你不需要修改你的構造函數。

更新

注意:spread 語法只復制屬性,所以我改為使用Object.assign

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM