有条件地在 Angular 2 或 4 中将输入字段设为只读:建议 + 最佳/采用哪种方式

Posted

技术标签:

【中文标题】有条件地在 Angular 2 或 4 中将输入字段设为只读:建议 + 最佳/采用哪种方式【英文标题】:Conditionally make input field readonly in Angular 2 or 4: Advice + Best/which way to do it 【发布时间】:2017-12-26 20:06:53 【问题描述】:

我试图回答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 引用 HTMLInputElementElement 是一种不好的做法吗? 只是,我经常看到使用ElementRef 或从ElementRef 链接到nativeElement 的示例。

由于 VS Studio 没有针对这些的 Intelli-sense,我突然觉得自己在黑暗中编码。即,您永远不会收到有关 setAttribute 或 removeAttribute 方法、它们的参数要求等的反馈。 (我也知道 As to cast)


    然后,在查看文档后,我怀疑您可以直接在 HTML 模板中的输入上执行此操作:

<input [attr.readonly]= "isReadOnly">

IIRC 我认为您必须以这种方式使用 Typescript 中的属性获取:

get isReadOnly() :boolean 

这种方式有效吗?


    我想知道,你能不能在 HTML 模板中也做方法语法:

<input [attr.readonly]= "isReadOnly()">

打字稿

isReadOnly() :boolean 

这种方式有效吗?


4. 总之,最好的方法是什么?

更新:还有 *ngIF 所以你输出两个具有相同名称的输入元素之一。但在我看来,这听起来就像是一把大锤敲碎了坚果。

【问题讨论】:

Define valid.... 因为如果你问它是否有效,那么测试它并找出答案。这是一个非常广泛的问题......我在不同的场合使用2 &amp; 3,具体取决于我需要计算什么来确定布尔值。 【参考方案1】:

您需要使用以下(Angular 4):

<input [readonly]="isReadOnly">

如果您使用att.readonly,则输入将始终为只读,因为readonly 属性将存在,​​即使其值为false。通过使用[readonly],Angular 只会在isReadOnly 为真时放置属性。

在 HTML 中,以下内容足以使输入变为只读:

<input readonly>

【讨论】:

这成功了!由于我的条件取决于 FormControl 值,并且我必须将数据共享给子组件,因此我最终获得了一些额外的代码。在父模板中:&lt;child-component [isReadOnly]="isSomeFormControlName.value === 'true'"&gt; 和我的子组件中的这段代码:@Input() isReadOnly: boolean;【参考方案2】:

一切都取决于您想要实现的目标。乍一看,我会说 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;

【讨论】:

如果您使用att.readonly,那么输入将始终为只读,因为readonly 属性将存在,​​即使其值为false。通过使用[readonly],Angular 只会在isReadOnly 为真时放置属性。这个答案是错误的。阅读接受的答案。【参考方案3】:

它们都不适合我。最后通过创建自定义指令 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

【讨论】:

【参考方案4】:

您可以使用&lt;input readonly=" variable &gt;"

在您的 *.component.ts 中,初始化变量:

private variable: boolean = true;

【讨论】:

这会将只读属性添加到输入,而不管variable 的值如何。【参考方案5】:

component.html

<input matInput formControlName="status" [readonly]="!status" />

组件.ts

// when you want to be read-only
isReadOnly = true;
// whe you want to be editable
isReadOnly = false;

【讨论】:

为什么更改isReadOnly 会对html 输入或formControl 做任何事情?在您的示例中,没有任何内容绑定到 isReadOnly

以上是关于有条件地在 Angular 2 或 4 中将输入字段设为只读:建议 + 最佳/采用哪种方式的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 中将 csv 或 excel 文件转换为 sql 输入数组?

在 Angular 2 中将时间 hh:mm:ss 转换为 GMT 时间格式

在Angular2中将管道添加到formControlName

如何使用Angular 6在一个输入中将多个对象发送到嵌套子组件

如何在一组行之后或有条件地在没有 PL/SQL 块的情况下增加 oracle 序列?

Python:有条件地在抓取过程中跳过url