Каков наилучший способ условного применения атрибутов в AngularJS?

Мне нужно иметь возможность добавлять, например, "contenteditable" к элементам, на основе логической переменной в области.

Пример использования:

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

Приведёт к добавлению contenteditable = true в элемент, если для параметра $scope.editMode установлено значение true. Есть ли какой-то простой способ реализовать это поведение класса ng-типа? Я рассматриваю возможность написания директивы и совместного использования, если нет.

Edit: Я вижу, что, похоже, есть некоторые сходства между моей предложенной директивой attrs и ng-bind-attrs, но она была удалена в 1.0.0.rc3, почему так?

Ответ 1

Я использую следующее, чтобы условно установить класс attr, когда ng-класс не может использоваться (например, при стилизации SVG):

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

Такой же подход должен работать и для других типов атрибутов.

(Я думаю, вам нужно быть на последнем неустойчивом Angular, чтобы использовать ng-attr-, я в настоящее время на 1.1.4)

Ответ 2

Вы можете префиксные атрибуты с ng-attr для eval выражения Angular. Когда результат выражений undefined, это удаляет значение из атрибута.

<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>

При использовании этого трюка в директиве. Атрибуты для директивы будут ложными, если они не имеют значения.

Например, приведенное выше было бы ложным.

function post($scope, $el, $attr) {
      var url = $attr['href'] || false;
      alert(url === false);
}

Ответ 3

Я получил эту работу, установив жесткий атрибут. И контроль применимости атрибута с использованием логического значения для атрибута.

Вот фрагмент кода:

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

Надеюсь, это поможет.

Ответ 4

В последней версии Angular (1.1.5) они включили условную директиву ngIf. Он отличается от ngShow и ngHide тем, что элементы не скрыты, но вообще не включены в DOM. Они очень полезны для компонентов, которые являются дорогостоящими для создания, но не используются:

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

Ответ 5

Чтобы получить атрибут для отображения определенного значения на основе логической проверки или полностью исключить, если ошибка boolean не удалась, я использовал следующее:

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

Пример использования:

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

Выведет <div class="itWasTest"> или <div> на основе значения params.type

Ответ 6

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

будет выдавать, когда isTrue = true: <h1 contenteditable="true">{{content.title}}</h1>

и когда isTrue = false: <h1>{{content.title}}</h1>

Ответ 7

В отношении принятого решения, опубликованного Эшли Дэвис, описанный метод все еще печатает атрибут в DOM, независимо от того, что назначенное ему значение undefined.

Например, при настройке поля ввода как с ng-моделью, так и с атрибутом 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:)

Ответ 8

Я на самом деле написал патч, чтобы сделать это несколько месяцев назад (после того, как кто-то спросил об этом в #angularjs на freenode).

Вероятно, он не будет объединен, но он очень похож на ngClass: https://github.com/angular/angular.js/pull/4269

Независимо от того, объединяется он или нет, существующие материалы ng-attr- *, вероятно, подходят для ваших нужд (как указывали другие), хотя это может быть немного clunkier, чем более функциональные функции ngClass, которые вы предлагаете.

Ответ 9

Также вы можете использовать выражение, подобное этому:

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

Ответ 10

Изменение: Этот ответ относится к Angular2+! Извините, я пропустил тег!

Оригинальный ответ:

Что касается очень простого случая, когда вы хотите применить (или установить) атрибут, только если было задано определенное входное значение, это так же просто, как

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

Это так же, как:

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

(Таким образом, optionValue применяется, если задано, иначе выражение ложно, а атрибут не применяется.)

Пример: у меня был случай, когда я позволил применить цвет, но также и произвольные стили, где атрибут цвета не работал, поскольку он уже был установлен (даже если цвет @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" был установлен только тогда, когда там присутствовал атрибут color, иначе можно было бы использовать атрибут color в строке "styles".

Конечно, это также может быть достигнуто с

[style.color]="color" 

а также

@Input color: (string | boolean) = false;

Ответ 11

Для проверки поля ввода вы можете:

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

Это применит атрибут max к 100, только если discountType определяется как %

Ответ 12

На всякий случай вам понадобится решение для Angular 2, тогда его простое использование связывания свойств, как показано ниже, например, вы хотите сделать ввод только для чтения условно, а затем добавить квадратные скобки, а затем добавить знак и выражение.

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