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

257

Мне нужно иметь возможность добавлять, например, "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
    Я не встречал ничего подобного. Я голосую, сделай это! : D Может быть, представить его в угловой проект. Синтаксис, который лучше соответствует классу ng, был бы хорош. ng-attr="expression" .
  • 0
    Я определенно считаю, что да!
Показать ещё 5 комментариев
Теги:
angularjs-directive

11 ответов

261
Лучший ответ

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

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

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

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

  • 1
    Вы также можете использовать этот метод с другими вещами, кроме логических, например, проверять, установлена ли переменная для чего-то определенного. code class = "{{varToCheck == 'valueToCheck' && 'class-if-true' || 'class-if-false'}}" code
  • 96
    Просто чтобы прояснить этот ответ: если вы ng-attr- любому атрибуту префикс ng-attr- , то компилятор ng-attr- префикс и добавит атрибут со значением, привязанным к результату углового выражения из исходного значения атрибута.
Показать ещё 11 комментариев
99

Вы можете префиксные атрибуты с 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
    Мне нравится этот ответ. Тем не менее, я не думаю, что если значение не определено, он будет скрывать атрибут. Я могу что-то упустить, хотя. Таким образом, первым результатом будет <a ng-attr-href="‹ карманный уровень || undefined routcast" href> Hello World </a>
  • 13
    @RomanK Привет, руководство гласит, что undefined - это особый случай. «При использовании ngAttr используется флаг allOrNothing в $ interpolate, поэтому, если какое-либо выражение в интерполированной строке приводит к неопределенности, атрибут удаляется и не добавляется в элемент».
Показать ещё 3 комментария
81

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

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

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

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

  • 0
    Так как angular может анализировать выражение IIF, это идеально подходит для оценки состояния в текущей области и присвоения значений на основе этого состояния.
22

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

<h1 ng-if="editMode" contenteditable=true>{{content.title}}</h1>
  • 32
    Я считаю, что ng-if работает только на уровне элемента, то есть вы не можете указать условие только для одного атрибута элемента.
  • 3
    Действительно, но тогда вы можете сделать <h1 ng-if="editMode" contenteditable="true"><h1 ng-if="!editMode">
Показать ещё 5 комментариев
12

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

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

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

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

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

9

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

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

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

  • 5
    Что делать, если я хочу что-то вроде <h1 contenteditable = "row">
  • 0
    <h1 ng-attr-contenteditable="{{isTrue ? 'row' : undefined}}">{{content.title}} </h1>
Показать ещё 1 комментарий
5

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

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

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

4

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

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

В отношении принятого решения, опубликованного Эшли Дэвис, описанный метод все еще печатает атрибут в 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:)

  • 0
    При таком подходе вы будете повторять один и тот же код.
  • 0
    Да, но это сохраняет декларацию модели в безопасности. Моя проблема с использованием принятого решения состояла в том, что атрибут value оказался в DOM, имея приоритет над объявлением модели. Таким образом, если атрибут значения пуст, а модель - нет, модель будет переопределена, чтобы принять пустое значение.
0

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

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню