在 Angular 2 或 4 中有条件地将输入字段设置为只读:建议 + Best/which 方法
Conditionally make input field readonly in Angular 2 or 4: Advice + Best/which way to do it
我正试图回答 someone elses question。在这样做的过程中,我意识到我对一些事情有相当多的不确定性。
我希望有人可以提供有关编号点 1..4:
的反馈
任务:有条件地使输入字段只读
HTML的相关部分:
<input type="text" placeholder="Club Name" #clubName>
将此添加到 Typescript 组件。
// class properties
@ViewChild('clubName')
inp:HTMLInputElement; // Could also use interface Element
// conditionally set in some other methods of class
inp.setAttribute('readonly', 'readonly');
inp.removeAttribute('readonly');
不得不说这对我来说是一个灰色地带。
- 在 Angular 2+ 中直接用
@ViewChild
引用 HTMLInputElement
或 Element
是一种不好的做法吗?
只是,我经常看到使用 ElementRef
或从 ElementRef
. 链接到 nativeElement
的示例
由于 VS Studio 没有这些智能感知,我突然觉得自己在黑暗中编码。即,您永远不会得到有关方法 setAttribute 或 removeAttribute、它们的参数要求等的反馈。
(我也知道 As to cast)
- 然后,在查看文档后,我怀疑您可以直接在 HTML 模板中输入:
<input [attr.readonly]= "isReadOnly">
IIRC 我认为你必须使用 属性 get in Typescript:
get isReadOnly() :boolean {
}
这种方式有效吗?
- 我想知道,您能否在 HTML 模板中也使用方法语法:
<input [attr.readonly]= "isReadOnly()">
打字稿
isReadOnly() :boolean {
}
这种方式有效吗?
4. 总之,最好的方法是什么?
更新:还有 *ngIF,因此您可以输出两个具有相同名称的输入元素之一。但这对我来说就像是用大锤敲碎坚果。
一切都取决于你想要达到的目标。乍一看,我会说 pct。 2 是最简单的方法:
<input [attr.readonly]= "isReadOnly">
然后,在您的组件上声明变量:
isReadOnly: boolean;
之后,您可以随意赋值:
// when you want to be read-only
isReadOnly = true;
// whe you want to be editable
isReadOnly = false;
您需要使用以下 (Angular 4):
<input [readonly]="isReadOnly">
如果您使用 att.readonly
,那么输入将始终是只读的,因为 readonly
属性将存在,即使它的值为 false。通过使用 [readonly]
Angular 将仅在 isReadOnly
为真时放置属性。
在 HTML 中,以下足以使输入为只读:
<input readonly>
您可以使用 <input readonly="{{ variable }}>"
.
在你的*.component.ts中,初始化变量:
private variable: boolean = true;
None 对我有用。最终通过创建自定义指令 angular 找到了解决方案。指令是 angular
的强大功能
- 创建自定义指令
@Directive({
selector: '[readonly],[readOnly]',
host: {
'[attr.readonly]': '_isReadonly ? "" : null'
}
})
class ReadonlyDirective {
_isReadonly = false;
@Input() set readonly (v) {
this._isReadonly = coerceBooleanProperty(v);
};
ngOnChanges(changes) {
console.log(changes);
}
}
- 添加到模块声明中
@NgModule({
...
declarations: [ ..., ReadonlyDirective ],
...
})
3. 现在是时候使用如下指令了。
<input [(ngModel)]="name" [readonly]="isReadonly" />
or
<input [(ngModel)]="name" readonly />
指令是 angular 的强大功能,我强烈建议您通过
https://angular.io/guide/attribute-directives
演示
https://stackblitz.com/edit/angular-readonly-input-aifncy?file=src/app/app.component.ts
component.html
<input matInput formControlName="status" [readonly]="!status" />
component.ts
// when you want to be read-only
isReadOnly = true;
// whe you want to be editable
isReadOnly = false;
我已经修好了:)
<input matInput type="text" (focus)="userNameFocus()" placeholder="Username" #u1 formControlName="userName" autocomplete="off" />
// initialize form on userName focus
<input matInput [type]="inputType" style="-webkit-text-security: square;" #p2 formControlName="password" />
有一个更简单的解决方案,只需使用
@Input('readonly') readonly: boolean
ngOnInit(){
this.readonly= this.readonly!== undefined && this.readonly!== false
}
现在您组件上的只读属性将是
false:
<app-component>
<app-component [readonly]='false'>
true:
<app-component readonly>
<app-component [readonly]='true'>
我正试图回答 someone elses question。在这样做的过程中,我意识到我对一些事情有相当多的不确定性。 我希望有人可以提供有关编号点 1..4:
的反馈任务:有条件地使输入字段只读
HTML的相关部分:
<input type="text" placeholder="Club Name" #clubName>
将此添加到 Typescript 组件。
// class properties
@ViewChild('clubName')
inp:HTMLInputElement; // Could also use interface Element
// conditionally set in some other methods of class
inp.setAttribute('readonly', 'readonly');
inp.removeAttribute('readonly');
不得不说这对我来说是一个灰色地带。
- 在 Angular 2+ 中直接用
@ViewChild
引用HTMLInputElement
或Element
是一种不好的做法吗? 只是,我经常看到使用ElementRef
或从ElementRef
. 链接到
nativeElement
的示例
由于 VS Studio 没有这些智能感知,我突然觉得自己在黑暗中编码。即,您永远不会得到有关方法 setAttribute 或 removeAttribute、它们的参数要求等的反馈。 (我也知道 As to cast)
- 然后,在查看文档后,我怀疑您可以直接在 HTML 模板中输入:
<input [attr.readonly]= "isReadOnly">
IIRC 我认为你必须使用 属性 get in Typescript:
get isReadOnly() :boolean {
}
这种方式有效吗?
- 我想知道,您能否在 HTML 模板中也使用方法语法:
<input [attr.readonly]= "isReadOnly()">
打字稿
isReadOnly() :boolean {
}
这种方式有效吗?
4. 总之,最好的方法是什么?
更新:还有 *ngIF,因此您可以输出两个具有相同名称的输入元素之一。但这对我来说就像是用大锤敲碎坚果。
一切都取决于你想要达到的目标。乍一看,我会说 pct。 2 是最简单的方法:
<input [attr.readonly]= "isReadOnly">
然后,在您的组件上声明变量:
isReadOnly: boolean;
之后,您可以随意赋值:
// when you want to be read-only
isReadOnly = true;
// whe you want to be editable
isReadOnly = false;
您需要使用以下 (Angular 4):
<input [readonly]="isReadOnly">
如果您使用 att.readonly
,那么输入将始终是只读的,因为 readonly
属性将存在,即使它的值为 false。通过使用 [readonly]
Angular 将仅在 isReadOnly
为真时放置属性。
在 HTML 中,以下足以使输入为只读:
<input readonly>
您可以使用 <input readonly="{{ variable }}>"
.
在你的*.component.ts中,初始化变量:
private variable: boolean = true;
None 对我有用。最终通过创建自定义指令 angular 找到了解决方案。指令是 angular
的强大功能- 创建自定义指令
@Directive({
selector: '[readonly],[readOnly]',
host: {
'[attr.readonly]': '_isReadonly ? "" : null'
}
})
class ReadonlyDirective {
_isReadonly = false;
@Input() set readonly (v) {
this._isReadonly = coerceBooleanProperty(v);
};
ngOnChanges(changes) {
console.log(changes);
}
}
- 添加到模块声明中
@NgModule({
...
declarations: [ ..., ReadonlyDirective ],
...
})
<input [(ngModel)]="name" [readonly]="isReadonly" />
or
<input [(ngModel)]="name" readonly />
演示 https://stackblitz.com/edit/angular-readonly-input-aifncy?file=src/app/app.component.ts
component.html
<input matInput formControlName="status" [readonly]="!status" />
component.ts
// when you want to be read-only
isReadOnly = true;
// whe you want to be editable
isReadOnly = false;
我已经修好了:)
<input matInput type="text" (focus)="userNameFocus()" placeholder="Username" #u1 formControlName="userName" autocomplete="off" />
// initialize form on userName focus
<input matInput [type]="inputType" style="-webkit-text-security: square;" #p2 formControlName="password" />
有一个更简单的解决方案,只需使用
@Input('readonly') readonly: boolean
ngOnInit(){
this.readonly= this.readonly!== undefined && this.readonly!== false
}
现在您组件上的只读属性将是
false:
<app-component>
<app-component [readonly]='false'>
true:
<app-component readonly>
<app-component [readonly]='true'>