【问题标题】:Angular 8 getRole is not a function in nested objectAngular 8 getRole 不是嵌套对象中的函数
【发布时间】:2020-02-22 23:29:42
【问题描述】:

我有一个 API,它返回 Profile 信息,我正在我的 HTTP 服务中获取它。嵌套对象User 有一个方法getRole()。但是当我试图调用这个方法时,我得到了

ERROR TypeError: _co.profile.user.getRole 不是函数

当我从我的其他服务获取User 时,它只返回User 实体,我可以毫无问题地调用此函数。

我错过了什么?

型号

export class Profile {
  user: User;
  apiKeys: ApiKey[];
}

export class User {
  user: string;
  firstname: string;
  surname: string;
  email: string;
  role: Role;
  active: boolean;

  getRole() {
    switch (this.role) {
      case Role.READ: {
        return "READ";
      }
      case Role.WRITE: {
        return "WRITE";
      }
      case Role.ADMIN: {
        return "ADMIN";
      }
      default : {
        return "READ";
      }
    }
  }
}

ProfileService.ts

getProfile(): Observable<Profile> {
    return this.http.get<Profile>(this.profileUrl).pipe(catchError(this.handleError));
}

Component.ts

profile: Profile;
isProfileAvailable:boolean = false;

ngOnInit() {
  this.settingsService.getProfile().subscribe(profile => {
    this.profile = profile;
    this.isProfileAvailable = true;
   });
}

Component.html

<p-fieldset [legend]="Profile" *ngIf="isProfileAvailable">
    <div><b>User: </b>{{profile.user.firstname}}</div>
    <div><b>E-mail: </b>{{profile.user.email}}</div>
    <div><b>Role: </b>{{profile.user.getRole()}}</div>
</p-fieldset>

【问题讨论】:

  • 请对我们的回答提供一些反馈。谢谢!
  • @Blauharley 这些天我一直很忙,但我会尽快尝试您的解决方案并给您反馈。
  • 请提供一些反馈。
  • @Blauharley 抱歉让我等了这么久,我终于有时间看看你的解决方案了。非常感谢,成功了!
  • 不客气。谢谢!

标签: angular angular-http ngoninit


【解决方案1】:

调用http.get&lt;Profile&gt; 不会自动初始化Profile 类型的对象,因此属性user 也不是User 类型的对象并且没有得到方法getRole

您可以使用Object.assign 来初始化对象及其属性。由于有两种类类型(ProfileUser),它们都可以从 Base-Class 扩展来处理这两种类型的属性分配。

型号:

// Use a Base class to assign all properties with objects both of type Profile and User
class Base {
    constructor(properties?: any) {
        (Object as any).assign(this, properties);
    }
}

export class User extends Base {
    user: string;
    firstname: string;
    surname: string;
    email: string;
    role: Role;
    active: boolean;

    getRole() {
        switch (this.role) {
            case Role.READ: {
                return "READ";
            }
            case Role.WRITE: {
                return "WRITE";
            }
            case Role.ADMIN: {
                return "ADMIN";
            }
            default : {
                return "READ";
            }
        }
    }  
}

export class Profile extends Base {
    user: User;
    apiKeys: ApiKey[];

    // take advantage of Object.assign
    // to initialize an instance of type Profile 
    // along with it's property user
    constructor(properties?: any) {
        super(properties);
        this.user = new User(properties.user);
    }
}

ProfileService.ts

getProfile(): Observable <Profile> {
    return this.http.get<Profile>(this.profileUrl).pipe(catchError(this.handleError));
}

Component.ts

profile: Profile;
isProfileAvailable:boolean = false;

ngOnInit()
{
    this.settingsService.getProfile().subscribe(profileData => {
        // assuming that profileData looks like this:
        /*
        {
            user: {
                user: 'user',
                firstname: 'firstname',
                surname: 'surname',
                email: 'email',
                active: true
            }
        }
        */
        this.profile = new Profile(profileData);
        this.isProfileAvailable = true;
    });
}

【讨论】:

    【解决方案2】:

    Blauharley 回答就像一个魅力。

    但是,由于我将所有模型都放在单独的文件中,因此我必须导出 Base 类:

    export class Base {
        constructor(properties?: any) {
            (Object as any).assign(this, properties);
        }
    }
    

    一切都按预期进行。

    【讨论】:

      【解决方案3】:

      您当前没有创建类的实例,因此类方法getRole() 不可用。使用this.http.get&lt;Profile&gt;,您只是告诉编译器您对 API 的期望符合您的类,它实际上并没有创建您的类或子类 User 的实例。

      您需要使用属性向您的类添加构造函数,并实际创建您的类的实例。这是一个简化的示例:

      export class User {
        role: string;
      
        constructor(role: string) {
          this.role = role;
        }
      
        getRole() {
          switch (this.role) {
            case 'READ': {
              return "READ";
            }
            case 'WRITE': {
              return "WRITE";
            }
            default: {
              return "READ";
            }
          }
        }
      }
      

      然后需要创建你的类的一个实例来访问类方法:

      ngOnInit() {
        let user = new User('WRITE');
        console.log(user.getRole());
      }
      

      STACKBLITZ

      此外,如果这将是您的类中唯一需要的方法,我只建议改用接口并编写一个独立的函数来检查角色,而不是经历创建类实例的麻烦。虽然这是一个非常自以为是的事情,所以如果你想使用类和类特定的方法,你确实需要走上面的路线。我只是喜欢个人使用接口:)

      【讨论】:

        猜你喜欢
        • 2021-03-31
        • 2019-12-24
        • 2020-06-11
        • 1970-01-01
        • 2020-06-29
        • 2018-08-29
        • 1970-01-01
        • 1970-01-01
        • 2015-04-20
        相关资源
        最近更新 更多