Angular 8 getRole 不是嵌套对象中的函数

Posted

技术标签:

【中文标题】Angular 8 getRole 不是嵌套对象中的函数【英文标题】:Angular 8 getRole is not a function in nested object 【发布时间】: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 抱歉让我等了这么久,我终于有时间看看你的解决方案了。非常感谢,成功了! 不客气。谢谢! 【参考方案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

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

【讨论】:

以上是关于Angular 8 getRole 不是嵌套对象中的函数的主要内容,如果未能解决你的问题,请参考以下文章

单击元素按钮时是不是会调用 Angular 8 中的生命周期挂钩

Angular 5中json对象的动态嵌套材质菜单

如何访问 Angular 中嵌套对象的属性?

Angular 8 组件嵌套在同一个组件事件发射器内

Angular 6,迭代角度模板中的深层嵌套对象

在angular7中读取复杂的嵌套json对象数组