【问题标题】:Angular 7 : Build on prod : Property 'service' is private and only accessible within class "Component"Angular 7:基于产品构建:属性“服务”是私有的,只能在“组件”类中访问
【发布时间】:2019-06-19 04:09:20
【问题描述】:

我正在使用 Angular 7。我运行此 cmd ng build --prod 构建以进行保护。

那时我正在缓存此错误(属性“服务”是私有的,只能在“登录组件”类中访问):

ERROR in src\app\login\login.component.html(5,33): : Property 'service' is private and only accessible within class 'LoginComponent'.
src\app\login\login.component.html(18,104): : Property 'service' is private and only accessible within class 'LoginComponent'.

这是我的 HTML 代码

<div id="login_section" class="d-flex justify-content-center align-items-center">
    <div class="login_cnt col-8 row">
        <div class="col-6 d-flex justify-content-center py-4">
            
            <form class="col-8" [formGroup]="service.loginform">
                <h2 class="text-center">User Login</h2>
                <mat-form-field class="col-12">
                  <input matInput type="text" placeholder="Username" formControlName="username" >
                  <mat-error>Username is Required</mat-error>
                </mat-form-field>
              
                <mat-form-field class="col-12">
                  <input matInput [type]="hide ? 'password' : 'text'" formControlName="password" placeholder="Password">
                  <mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
                  <mat-error>Password is Required</mat-error>
                </mat-form-field>
                <a href="#" class="float-left lnk_forgot h7">Forgot Password</a>
                <button mat-raised-button color="primary" class="float-right" [routerLink]="['/home']" [disabled]="service.loginform.invalid">Login</button>
              </form>
        </div>
    </div>
</div>

这是我的 TS 文件

import { Component, OnInit } from '@angular/core';
import { LoginService } from '../shared/login.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
  username : string;
  password: string;
  hide = true;

  constructor(private service: LoginService) { }
  ngOnInit() {
  }

}

在运行 ng serve 时没有捕捉到它。

【问题讨论】:

标签: javascript html angular typescript production-environment


【解决方案1】:

您需要公开访问说明符以使其可访问

constructor(public service: LoginService) { }

【讨论】:

  • 但是,我需要私人服务。因此如何改变我的代码结构
【解决方案2】:

您似乎正在使用 Ahead-of-Time 编译(在构建时),并且您正在尝试在其模板 @987654322 中访问组件的 私有 成员 (service) @,service.loginform。但是在模板和ahead-of-time compilation使用的情况下必须是public

constructor(private service: LoginService) { }

应该是:

// your component: change private service to public service
constructor(public service: LoginService) { }

// then you can use it like this in the template of your component:
[formGroup]="service.loginform"

[disabled]="service.loginform.invalid"

如果您需要一个服务是私有的并且仍然需要在组件的模板中使用它的一些成员,请使用get 或其他方法(公共)返回该成员:

// your component
constructor(private service: LoginService) { }

get loginForm() {
  return this.service.loginform;
}

get loginIsInvalid(): boolean {
  return this.service.loginform.invalid;
}

// then in the template of your component you can use:
[formGroup]="loginform"

[disabled]="loginIsInvalid"

【讨论】:

    【解决方案3】:

    有两种方法可以解决此问题。
    1.
    private service: LoginService 更改为 public service: LoginService
    由于您在编译期间使用 AOT,因此您无法在 HTML 模板中访问组件的私有属性。

    2.

    如果你想保持你的服务私有,你可以在控制器中提供一个返回服务属性的公共方法。您可以从 HTML 模板调用此方法。应该是这样的:

    模板:

    <div id="login_section" class="d-flex justify-content-center align-items-center">
        <div class="login_cnt col-8 row">
            <div class="col-6 d-flex justify-content-center py-4">
    
                <form class="col-8" [formGroup]="getLoginForm()"> <!-- Change here-->
                    <h2 class="text-center">User Login</h2>
                    <mat-form-field class="col-12">
                      <input matInput type="text" placeholder="Username" formControlName="username" >
                      <mat-error>Username is Required</mat-error>
                    </mat-form-field>
    
                    <mat-form-field class="col-12">
                      <input matInput [type]="hide ? 'password' : 'text'" formControlName="password" placeholder="Password">
                      <mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
                      <mat-error>Password is Required</mat-error>
                    </mat-form-field>
                    <a href="#" class="float-left lnk_forgot h7">Forgot Password</a>
                    <button mat-raised-button color="primary" class="float-right" [routerLink]="['/home']" [disabled]="getLoginForm().invalid">Login</button> <!-- Change here-->
                  </form>
            </div>
        </div>
    </div>
    

    控制器:

    import { Component, OnInit } from '@angular/core';
    import { LoginService } from '../shared/login.service';
    
    @Component({
      selector: 'app-login',
      templateUrl: './login.component.html',
      styleUrls: ['./login.component.scss']
    })
    export class LoginComponent implements OnInit {
      username : string;
      password: string;
      hide = true;
    
      constructor(private service: LoginService) { }
      ngOnInit() {
      }
    
      getLoginForm() {
        return this.service.loginform;
      }
    }
    

    P.S:我暂时还没有自己测试过第二个。

    【讨论】:

      【解决方案4】:

      您是否担心必须调用函数而不是只使用模板中的变量?

      捕捉这个自执行函数提示:

      模板:

      <form class="col-8" [formGroup]="loginform"> <!-- Change here-->
      

      控制器:

      import { Component, OnInit } from '@angular/core';
      import { LoginService } from '../shared/login.service';
      
      @Component({
        selector: 'app-login',
        templateUrl: './login.component.html',
        styleUrls: ['./login.component.scss']
      })
      export class LoginComponent implements OnInit {
        username : string;
        password: string;
        hide = true;
      
        constructor(private service: LoginService) { }
        ngOnInit() {
        }
      
        loginform = (() -> this.service.loginform)(); /* Change here */
      }
      

      如果您需要在模板中访问该变量的某些内部字段,这会很有用。

      <form class="col-8" [formGroup]="loginform.SOME_FIELD.INNER_PROP">
      

      而不是

      <form class="col-8" [formGroup]="getLoginForm().SOME_FIELD.INNER_PROP">
      

      它看起来更方便和可读,恕我直言。

      【讨论】:

        猜你喜欢
        • 2018-01-01
        • 2017-08-27
        • 2019-06-17
        • 2016-12-14
        • 2017-02-23
        • 2017-08-25
        • 2021-01-10
        相关资源
        最近更新 更多