ChatGPT解决这个技术问题 Extra ChatGPT

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

我需要能够基于范围上的布尔变量向元素添加例如“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 之间似乎有一些相似之处,为什么会这样?

我还没有遇到过这样的事情。我投票去做! :D 也许将它提交给 Angular 项目。更好地匹配 ng-class 的语法会很好。 ng-attr="expression"
我肯定认为是的!
这实际上与 ngClass 或 ngStyle 不同,因为它们控制 single 属性,而您想要控制 any 属性。我认为创建一个 contentEditable 指令会更好。
@JoshDavidMiller 对此 +1。我认为能够控制任何属性都有一点好处,尤其是考虑到复杂性。您可以有条件地作用于变量的指令。
<h1 ng-attr-contenteditable="{{editMode && true : false}}">{{content.title}}</h1>

A
Ashley Davis

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

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

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

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


只是为了澄清这个答案:如果您为 any 属性添加 ng-attr- 前缀,那么编译器将去除前缀,并将其 value 绑定到结果的属性添加角度表达式来自原始属性值。
在我看来,如果您使用三元运算符会更容易阅读,在 1.1.5 中添加了对它的支持。这看起来像: {{ someConditionalExpression ? 'class-when-true' : 'class-when-false' }}
这种方法的问题在于,无论结果如何,都会创建属性。理想情况下,我们希望控制属性是否被创建。
请注意,ng-attr-stuff 已从 Angular 1.2 中删除。这个答案不再有效。
你错了。此项目 github.com/codecapers/AngularJS-FlowChart 使用 Angular 1.2 和 ng-attr-。最新的文档(Angular 1.4)仍然包括 ng-attr-
K
Kana Ki

您可以在属性前面加上 ng-attr 来评估 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);
}

我喜欢这个答案。但是,我认为如果 value 未定义,它不会隐藏该属性。不过,我可能会遗漏一些东西。所以第一个结果是 Hello World
@RomanK 嗨,手册指出 undefined 是一种特殊情况。 "在使用ngAttr时,使用了$interpolate的allOrNothing标志,所以如果插值字符串中的任何表达式导致undefined,该属性将被移除,而不是添加到元素中。"
只是为了帮助任何未来的读者,Angular 1.3 中似乎添加了“未定义”行为。我正在使用 1.2.27,目前必须使用 IE8。
为了确认更多 Angular 1.2.15 将显示 href 即使值未定义,看起来未定义的行为从 Angular 1.3 开始,如上述注释所述。
请务必注意,ng-attr-foo 仍会始终调用 foo 指令(如果存在),即使 ng-attr-foo 的计算结果为 undefineddiscussion
j
jsbisht

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

这是代码片段:

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

我希望这有帮助。


由于 Angular 可以解析 IIF 表达式,因此它非常适合评估当前范围内的状态并基于该状态分配值。
B
Brian Genisio

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

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

我相信 ng-if 仅适用于元素级别,也就是说,您不能仅对元素的一个属性指定条件。
确实,但你可以这样做 <h1 ng-if="editMode" contenteditable="true"><h1 ng-if="!editMode">
但是请注意,ng-if 创建了一个新范围。
@ShimonRachlenko 同意!这可能是混乱和错误的一大来源。 ng-if 创建一个新范围,但 ng-show 没有。这种矛盾一直是我的痛处。对此的防御性编程反应是:“总是绑定到表达式中的点”,这不会成为问题。
如果你想添加一个实际上是指令的属性,这很好用。对代码重复感到羞耻
G
Glen

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

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

示例用法:

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

将根据 params.type 的值输出 <div class="itWasTest"><div>


G
Garfi

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

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

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


如果我想要类似

的东西怎么办

<h1 ng-attr-contenteditable="{{isTrue ? 'row' : undefined}}">{{content.title}} </h1>
这应该是我接受的答案。我的场景是<video ng-attr-autoplay="{{vm.autoplay || undefined}}" />
a
alexc

关于已接受的解决方案,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 指令中使用更详细的检查:)


使用这种方法,您将重复相同的代码。
没错,但它保证了模型声明的安全。我使用公认解决方案的问题是 value 属性最终出现在 DOM 中,优先于模型声明。因此,如果 value 属性为空但模型不是,则模型将被覆盖以获取空值。
K
Kamuran Sönecek

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

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

c
chronicsalsa

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

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

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


N
Nestor Britez

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

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

仅当 discountType 定义为 % 时,才会将属性 max 应用于 100


Z
Zaphoid

编辑:这个答案与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;

Angular.JS 是 Angular 1,它与 Angular 2+ 非常不同。您的解决方案回答了 Angular 2+,但要求使用 AngularJS (1)。
@ssc-hrep3:你是对的。对不起,我错过了!谢谢。我编辑了答案以指出这一点。 :-)
angularjs 不是 angular,angularjs 是 angular 1
R
Richard Strickland

能够得到这个工作:

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

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


S
Sanjay Singh

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

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

是 angularjs (angular1) 不是 angular (angular2)
angular 2+ 和 Angular JS 不一样,它们更像是完全不同的产品。