如何在Angular 2中添加条件属性?

393

如何有条件地添加元素属性,例如复选框的checked属性?

在之前的Angular版本中有NgAttrNgChecked,它们似乎都提供了我所需要的功能。然而,在Angular 2中似乎不存在这些属性,我也没有找到其他提供此功能的方法。


1
参见:https://dev59.com/O1oV5IYBdhLWcg3wc-cm - Matty
参见:https://dev59.com/QFgQ5IYBdhLWcg3w0HOW#43765804 - aloisdg
2
谷歌员工们,如果您想要向Angular组件添加一个没有值的属性,请参阅此处。 (https://dev59.com/SFcP5IYBdhLWcg3wr8Dj#43990083) - Frank N
10个回答

785

null将其删除:

[attr.checked]="value ? '' : null"
[attr.checked]="value ? 'checked' : null"

提示:

属性 vs 属性值

当您添加此绑定的 HTML 元素没有与绑定中使用的名称相同的属性(在本例中为 checked),并且也没有应用任何 Angular 组件或指令到具有 @Input() checked; 的相同元素上时,则不能使用 [xxx]="..."

请参阅HTML 中属性和属性值之间的区别是什么?

在没有该属性时绑定到什么

根据您所尝试完成的任务,替代方案是 [style.xxx]="..."[attr.xxx]="..."[class.xxx]="..."

由于 <input> 只有一个 checked 属性,但没有 checked 属性,因此 [attr.checked]="..." 是这种特定情况下正确的方法。

属性只能处理字符串值

常见陷阱还包括对于 [attr.xxx]="..." 绑定,其值 (...) 总是被字符串化。只有属性和 @Input() 可以接收其他值类型,例如布尔值、数字、对象,等等。

大多数元素的属性和属性值是相互关联并具有相同的名称。

属性-属性值连接

当绑定到属性值时,属性也只接收来自属性值的字符串化值。
当绑定到属性时,属性接收绑定到它的值(布尔值、数字、对象等),而属性值再次是字符串化的值。

两种情况下属性和属性值的名称不匹配。

自那时起,Angular 已经发生了变化,并知道这些特殊情况并处理它们,以便您可以绑定到 <label [for]=" 即使没有这样的属性(对于 colspan 也是如此)。


4
可以省略 "attr." 前缀。 - Filip Stachowiak
21
如果这样做,它就不会成为一个属性。许多元素上有各种属性,其中元素本身反映了绑定到属性的值到一个属性(也反过来)。在这种情况下,您不需要使用 attr.。但是如果您想添加自定义属性,则肯定需要 attr. 前缀。 - Günter Zöchbauer
21
需要明确的是,你必须使用 attr. 这一部分。我试图设置 [href] 属性,并且只想在该项的 href 属性存在时才设置它。如果没有 [attr.href],这将会添加一个值为“null”的 href 属性,当它被点击时,会刷新当前页面。有了 [attr.href] 就解决了这个问题。 - dudewad
@dudewad,这对我来说听起来不太对。如果您在具有href属性的元素上设置href,则无需使用attr。肯定还有其他问题。 - Günter Zöchbauer
attr.不是一个指令,而是Angular的特殊语法。我不确定我完全理解了你的评论。也许你想要使用<a [href]="item?.href"来防止在item最初为undefinednull时出现错误。 - Günter Zöchbauer
显示剩余5条评论

49

在Angular 2中,属性语法是

<div [attr.role]="myAriaRole">

将属性“role”绑定到表达式“myAriaRole”的结果。

因此可以这样使用:

[attr.role]="myAriaRole ? true: null"

11
иҝҷйҮҢзҡ„й—®йўҳеңЁдәҺпјҢеҪ“дҪ зҡ„иЎЁиҫҫејҸдёәfalseж—¶пјҢDOMдёӯзҡ„еұһжҖ§е°ҶжҳҫзӨәдёә<div checked="false">гҖӮжҲ‘и®ӨдёәиҝҷдёҚжҳҜйў„жңҹзҡ„ж•ҲжһңгҖӮ - Günter Zöchbauer
9
感谢您,但我询问的是如何有条件地添加属性,而不是有条件地赋值。 - Jon Miles
你甚至可以省略 "attr." 前缀。 - Filip Stachowiak
2
@FilipStachowiak 那么它就不会成为一个属性。许多元素上有各种属性,其中元素本身反映了绑定到属性的值到属性(以及另一个方向)。在这种情况下,您不需要 attr.。但是,如果您想添加自定义属性,则绝对需要 attr. 前缀。 - Günter Zöchbauer
哦,这个 : null 真是太棒了,我从来不知道它可以用在条件语句中!感谢你提供的解决方案。 - pinarella

21

优化Günter Zöchbauer的答案:

现在看起来有些不同了。我试图这样做是为了有条件地将href属性应用于锚标记。你必须使用未定义的值来表示“不适用”的情况。例如,我将演示如何有条件地应用href属性的链接。

--编辑-- 看起来Angular已经改变了一些东西,所以null现在可以按预期工作了。我已经更新了示例以使用null而不是undefined

没有href属性的锚标记变成普通文本,表示链接的占位符,根据超链接规范

对于我的导航,我有一个链接列表,但其中一个链接代表当前页面。我不希望当前页面链接成为链接,但仍然希望它出现在列表中(它有一些自定义样式,但这个示例被简化了)。

<a [attr.href]="currentUrl !== link.url ? link.url : null">

我认为这比在span和anchor标签上使用两个*ngIf要更简洁。它还非常适合给按钮添加禁用属性。


13

如果你需要确切的checked,最好使用属性而不是属性值,并将某个布尔值分配给它:

<input type="checkbox" [checked]="smth">

如果您想有条件地添加任意属性,可以使用绑定方式实现:
<p [attr.data-smth]="smth">
  • 如果值为undefinednull,则不添加属性。
  • 如果值为空字符串,则添加属性但不添加值。
  • 否则,添加一个字符串化的值作为属性值。

当然,你也可以与attr.checked一同使用:

<input type="checkbox" [attr.checked]="smth ? '' : null">

但请注意,在这种情况下,属性与被选中的状态不同步,因此以下组合:
<input type="checkbox" [checked]="false" [attr.checked]="''">

会导致带有checked属性的复选框未被勾选。

以下是一个完整的示例:

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  template: `
    <p [attr.data-smth]="e">The value is: {{what(e)}}</p>
    <p [attr.data-smth]="s">The value is: {{what(s)}}</p>
    <p [attr.data-smth]="u">The value is: {{what(u)}}</p>
    <p [attr.data-smth]="n">The value is: {{what(n)}}</p>
    <p [attr.data-smth]="t">The value is: {{what(t)}}</p>
    <p [attr.data-smth]="f">The value is: {{what(f)}}</p>

    <input type="checkbox" [checked]="t">
    <input type="checkbox" [checked]="f">

    <input type="checkbox" [attr.checked]="t ? '' : null">
    <input type="checkbox" [attr.checked]="f ? '' : null">

    <input type="checkbox" [checked]="false" [attr.checked]="''">
  `,
  styles: [`
    p[data-smth] {
      color: blue;
    }
  `]
})
export class AppComponent {
  e = ""
  s = "abc"
  u = undefined
  n = null
  t = true
  f = false

  what(x) {
    return typeof x === 'string' ? JSON.stringify(x) : x + ""
  }
}

这是结果:

result screenshot

这是标记:

markdown screenshot


8
如果这是一个输入元素,你可以写类似于... <input type="radio" [checked]="condition">其中condition的值必须为true或false。
同样适用于样式属性... <h4 [style.color]="'red'">一些文本</h4>

5

您可以使用这个。

<span [attr.checked]="val? true : false"> </span>


你使用了 'val' 来检查属性值。如果它为 true,则返回 true,否则返回 false。 - WapShivam

1

如果有人在已经存在的scss文件中编写HTML,您可以使用更好的方法。

[attr.role]="<boolean>"

scss

[role = "true"] { ... }

那样你就不需要每次都使用 <boolean> ? true : null

1
这并不适用于每种情况。例如,它不能与select元素上的multiple属性一起使用。 - smartmouse

0

我想在代码中只对特定字段添加工具提示,如下所示,但是如果要在多个字段上添加工具提示,则可以使用以下方法创建数组进行验证:

拥有自定义data-tooltip属性的多个元素:

1: ['key1ToHaveTooltip','key2ToHaveTooltip']包含(key)

2:['key1ToHaveTooltip','key2ToHaveTooltip'] .indexOf(key)> -1

以便在多个元素上拥有工具提示属性。

   <div *ngFor="let key of Keys"
             [attr.data-tooltip]="key === 'IwantOnlyThisKeyToHaveTooltipAttribute' 
                                           ? 'Hey! I am a tooltip on key matched'
                                           : null">
   </div>

-3

在这里,仅当'isValid'为真/包含任何值时,才打印该段落

<p *ngIf="isValid ? true : false">Paragraph</p>

2
这不是他的问题。这样做没有帮助,只会增加混乱。 - Andrew Koper

-8

内联地图也很方便。

它们更加明确易读。

[class]="{ 'true': 'active', 'false': 'inactive', 'true&false': 'some-other-class' }[ trinaryBoolean ]"

如果你不喜欢三元语法或者ngIf等方式,这是完成相同任务的另一种方法。


2
一个类和一个属性(问题所涉及的内容)是完全不同的东西。 - Günter Zöchbauer
2
你也可以花点功夫把它变成一个合适的回答,这样我就有理由重新考虑我的投票了。如果你没有添加评论,我也可以直接点踩而不让你知道点踩的原因。 - Günter Zöchbauer
1
@Cody,你能否解释一下(并提供示例代码),你的方法如何与checked属性一起使用(将其添加/从输入标签中删除)在<input type="checkbox" name="vehicle" value="Car" checked>中?(如果我们在您的代码中将class更改为checkbox,它将无法正常工作(我已经检查过了)) - Kamil Kiełczewski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接