在AngularJS中有条件地应用属性的最佳方法是什么?

时间:2013-03-29 02:25:00

标签: angularjs angularjs-directive

我需要能够根据范围内的布尔变量为元素添加“contenteditable”。

使用示例:

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

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

修改 我可以看到我提议的attrs指令和ng-bind-attrs, but it was removed in 1.0.0.rc3之间似乎有一些相似之处,为什么会这样?

13 个答案:

答案 0 :(得分:264)

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

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

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

(我认为你需要使用最新的不稳定Angular来使用ng-attr-,我目前正在使用1.1.4)

答案 1 :(得分:114)

您可以使用ng-attr为属性添加前缀以评估Angular表达式。如果表达式的结果未定义,则会从属性中删除该值。

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

将产生(当值为假时)

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

所以不要使用false,因为这会产生“&#34; false&#34;作为价值。

<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);
}

答案 2 :(得分:92)

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

以下是代码段:

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

我希望这会有所帮助。

答案 3 :(得分:22)

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

<h1 ng-if="editMode" contenteditable=true>{{content.title}}</h1>

答案 4 :(得分:13)

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

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

使用示例:

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

根据<div class="itWasTest">

的值输出<div>params.type

答案 5 :(得分:9)

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

当isTrue = true时,

将产生: <h1 contenteditable="true">{{content.title}}</h1>

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

答案 6 :(得分:6)

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

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

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

无论myValue背后是什么,属性仍会在DOM中打印出来,因此会被解释。然后,Ng模型被覆盖。

有点不愉快,但使用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指令中使用更详细的检查:)

答案 7 :(得分:5)

几个月前我(实际上是有人在freenode的#angularjs上询问过这个问题)之后写了一个补丁。

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

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

答案 8 :(得分:5)

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

<h1 ng-attr-contenteditable="{{ editMode ? true : false }}"></h1>

答案 9 :(得分:1)

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

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

仅当max定义为100

时,才会将属性discountType应用于%

答案 10 :(得分:1)

仅在您需要Angular 2解决方案的情况下,然后使用以下简单的属性绑定即可,例如您想使输入有条件地为只读,然后在方括号中添加attrbute,后跟=符号和表达式。

<input [readonly]="mode=='VIEW'"> 

答案 11 :(得分:1)

对于非常简单的情况,当您只想(设置)某个属性(如果设置了某个输入值)时,就像

一样简单
    - containerPort: 3011
    readinessProbe:
      tcpSocket:
        port: 3011
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 3011
      initialDelaySeconds: 15
      periodSeconds: 20

与以下相同:

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

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

示例:我有一种情况,我既应用颜色,又应用任意样式,其中color属性由于已经设置而无法使用(即使未提供@Input()颜色):< / p>

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

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

当然,也可以通过

实现
@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]="color" 

答案 12 :(得分:0)

能够正常工作:

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

这里的好处是,如果item.isSelected为false,那么该属性就不会被呈现。