Angular 7:基于产品构建:属性 'service' 是私有的,只能在 class "Component" 内访问
Angular 7 : Build on prod : Property 'service' is private and only accessible within class "Component"
我正在使用 Angular 7。我 运行 此 cmd ng build --prod
为保护而构建。
当时我正在缓存这个错误(属性 'service' 是私有的,只能在 class 'LoginComponent' 内访问):
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() {
}
}
当 运行ning ng serve 没有捕捉到它时。
您需要将访问说明符设置为 public 以使其可访问
constructor(public service: LoginService) { }
似乎您正在使用提前编译(在构建时),并且您正在尝试访问 private 成员 (service
)其模板中的组件 [disabled]="service.loginform.invalid"
、service.loginform
。但在模板中使用时必须是public,ahead-of-time compilation
:
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
或其他方法 (public) return该成员:
// 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"
有两种方法可以解决这个问题。
1.
将 private service: LoginService
更改为 public service: LoginService
由于您在编译期间使用 AOT,因此您无法在 HTML 模板中访问组件的私有属性。
2.
如果你想让你的服务保持私有,你可以在控制器中提供一个 public 方法,其中 returns 服务属性。您可以从 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: 第二个暂时没有自己测试
您是否担心必须调用函数而不是仅使用模板中的变量?
抓住这个自执行函数提示:
模板:
<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">
恕我直言,它看起来更加方便易读。
我正在使用 Angular 7。我 运行 此 cmd ng build --prod
为保护而构建。
当时我正在缓存这个错误(属性 'service' 是私有的,只能在 class 'LoginComponent' 内访问):
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() {
}
}
当 运行ning ng serve 没有捕捉到它时。
您需要将访问说明符设置为 public 以使其可访问
constructor(public service: LoginService) { }
似乎您正在使用提前编译(在构建时),并且您正在尝试访问 private 成员 (service
)其模板中的组件 [disabled]="service.loginform.invalid"
、service.loginform
。但在模板中使用时必须是public,ahead-of-time compilation
:
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
或其他方法 (public) return该成员:
// 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"
有两种方法可以解决这个问题。
1.
将 private service: LoginService
更改为 public service: LoginService
由于您在编译期间使用 AOT,因此您无法在 HTML 模板中访问组件的私有属性。
2.
如果你想让你的服务保持私有,你可以在控制器中提供一个 public 方法,其中 returns 服务属性。您可以从 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: 第二个暂时没有自己测试
您是否担心必须调用函数而不是仅使用模板中的变量?
抓住这个自执行函数提示:
模板:
<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">
恕我直言,它看起来更加方便易读。