304

我需要能够基于范围上的布尔变量向元素添加例如“contenteditable”。

示例使用:

<h1 attrs="{'contenteditable=\"true\"': editMode}">{{content.title}}</h1>

如果$scope.editMode设置为 ,将导致 contenteditable=true 添加到元素中true。有没有一些简单的方法来实现这个类似 ng-class 的属性行为?如果没有,我正在考虑编写指令并分享。

编辑: 我可以看到我提出的 attrs 指令和 ng-bind-attrs 之间似乎有一些相似之处,但是它在 1.0.0.rc3 中被删除了,为什么会这样?

4

13 回答 13

280

当无法使用 ng-class 时(例如在设置 SVG 样式时),我使用以下有条件地设置类 attr:

ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"

相同的方法应该适用于其他属性类型。

(我认为您需要使用最新的不稳定 Angular 才能使用 ng-attr-,我目前使用的是 1.1.4)

于 2013-05-21T12:15:30.937 回答
126

你可以在属性前面加上ng-attreval 一个 Angular 表达式。当表达式的结果未定义时,这会从属性中删除值。

<a ng-attr-href="{{value || undefined}}">Hello World</a>

将产生(当值为假时)

<a ng-attr-href="{{value || undefined}}" href>Hello World</a>

所以不要使用false,因为这会产生单词“false”作为值。

<a ng-attr-href="{{value || false}}" href="false">Hello World</a>

在指令中使用此技巧时。如果指令的属性缺少值,则它们的属性将为 false。

例如,以上将是错误的。

function post($scope, $el, $attr) {
      var url = $attr['href'] || false;
      alert(url === false);
}
于 2014-08-01T21:06:43.100 回答
99

我通过努力设置属性来完成这项工作。并使用属性的布尔值控制属性的适用性。

这是代码片段:

<div contenteditable="{{ condition ? 'true' : 'false'}}"></div>

我希望这有帮助。

于 2014-12-13T11:29:24.137 回答
21

在最新版本的 Angular (1.1.5) 中,它们包含了一个名为ngIf. 它的不同之ngShowngHide在于元素不是隐藏的,而是根本不包含在 DOM 中。它们对于创建成本高但未使用的组件非常有用:

<h1 ng-if="editMode" contenteditable=true>{{content.title}}</h1>
于 2013-07-09T16:48:47.083 回答
16

为了让属性基于布尔检查显示特定值,或者如果布尔检查失败则完全省略,我使用了以下内容:

ng-attr-example="{{params.type == 'test' ? 'itWasTest' : undefined }}"

示例用法:

<div ng-attr-class="{{params.type == 'test' ? 'itWasTest' : undefined }}">

将输出<div class="itWasTest"><div>基于值params.type

于 2015-09-10T22:10:53.393 回答
10

<h1 ng-attr-contenteditable="{{isTrue || undefined }}">{{content.title}}</h1>

当 isTrue=true 时会产生: <h1 contenteditable="true">{{content.title}}</h1>

当 isTrue=false 时: <h1>{{content.title}}</h1>

于 2015-06-05T08:29:30.573 回答
7

关于已接受的解决方案,Ashley Davis 发布的解决方案,所描述的方法仍然在 DOM 中打印属性,而不管它被分配的值是未定义的事实。

例如,在具有 ng-model 和 value 属性的输入字段设置上:

<input type="text" name="myInput" data-ng-attr-value="{{myValue}}" data-ng-model="myModel" />

不管 myValue 背后是什么,value属性仍然会打印在 DOM 中,因此会被解释。然后,Ng-model 被覆盖。

有点不愉快,但使用 ng-if 可以解决问题:

<input type="text" name="myInput" data-ng-if="value" data-ng-attr-value="{{myValue}}" data-ng-model="myModel" />
<input type="text" name="myInput" data-ng-if="!value" data-ng-model="myModel" />

我建议在 ng-if 指令中使用更详细的检查:)

于 2014-07-09T21:53:07.280 回答
6

你也可以使用这样的表达式:

<h1 ng-attr-contenteditable="{{ editMode ? true : false }}"></h1>
于 2015-12-22T14:30:30.150 回答
5

几个月前,我实际上写了一个补丁来做到这一点(在有人在 freenode 上的#angularjs 中询问它之后)。

它可能不会被合并,但它与 ngClass 非常相似:https ://github.com/angular/angular.js/pull/4269

无论是否合并,现有的 ng-attr-* 东西都可能适合您的需求(正如其他人所提到的),尽管它可能比您建议的更多 ngClass 风格的功能有点笨拙。

于 2013-11-30T17:48:46.577 回答
2

对于输入字段验证,您可以执行以下操作:

<input ng-model="discount" type="number" ng-attr-max="{{discountType == '%' ? 100 : undefined}}">

仅当定义max100discountType%

于 2016-04-14T18:45:06.530 回答
1

编辑:这个答案与Angular2+有关!对不起,我错过了标签!

原答案:

至于如果设置了某个 Input 值,您只想应用(或设置)一个属性的非常简单的情况,它就像

<my-element [conditionalAttr]="optionalValue || false">

它与以下内容相同:

<my-element [conditionalAttr]="optionalValue ? optionalValue : false">

(因此,如果给定,则应用 optionalValue,否则表达式为 false 并且不应用属性。)

示例:我有这样的情况,我让应用颜色但也应用任意样式,其中颜色属性不起作用,因为它已经设置(即使没有给出 @Input() 颜色):

@Component({
  selector: "rb-icon",
  styleUrls: ["icon.component.scss"],
  template: "<span class="ic-{{icon}}" [style.color]="color==color" [ngStyle]="styleObj" ></span>",
})
export class IconComponent {
   @Input() icon: string;
   @Input() color: string;
   @Input() styles: string;

   private styleObj: object;
...
}

因此,“style.color”仅在有颜色属性时才设置,否则可以使用“styles”字符串中的颜色属性。

当然,这也可以通过

[style.color]="color" 

@Input color: (string | boolean) = false;
于 2019-04-25T15:30:25.290 回答
1

能够得到这个工作:

ng-attr-aria-current="{{::item.isSelected==true ? 'page' : undefined}}"

这里的好处是,如果 item.isSelected 为 false,则根本不会呈现该属性。

于 2020-01-24T16:44:24.133 回答
0

以防万一您需要 Angular 2 的解决方案,那么它很简单,使用如下所示的属性绑定,例如,您想让输入有条件地只读,然后在方括号中添加 attrbute,后跟 = 符号和表达式。

<input [readonly]="mode=='VIEW'"> 
于 2018-07-20T21:10:47.693 回答