Как проверить тип переменной в ngIf в Angular2

Я изучаю Angular2. У меня есть компонент с переменной, которая является объектом. Я перебираю поля объекта, и в соответствии с типом данных этой позиции мне нужно визуализировать другой компонент. В этом случае я хочу сделать так, чтобыlabel еслиtypeof эта позицияnumber как бы то ни было это не работает

<div>
  <div *ngIf='obj'>
    <label *ngFor="let key of keys; let i = index">
      <label class='key'>{{key}}:</label>
      <label class='number' *ngIf='typeof obj[key] === "number"'>
      <!-- label class='number' *ngIf='obj[key] | typeof === "number"' -->
        {{ obj[key] }}
      </label>
    </label>
  </div>
</div>

Есть идеи?

Я также создал трубу, чтобы получитьtypeof которые работают, когда я печатаю значение, но не внутри * ngIf

 Mark Rajcok03 июн. 2016 г., 04:34
Смотрите разделШаблонные выраженияи, в частности, разделКонтекст выражения вРуководство по разработке синтаксиса шаблонов.

Ответы на вопрос(4)

но если вам нужно делать это во многих местах и ​​не хотите, чтобы вы проходили мимоisNumber вокруг, есть еще один вариант, который может работать, если вы используете его осторожно.

Вы можете проверить наличие свойств или методов, которые существуют наprototype объекта или типа, который вы ищете. Например, все числа имеютtoExponential функция, так:

<label class='number' *ngIf='obj[key] && obj[key].toExponential'>

Для функций, которые вы могли бы искатьcall, для строк вы можете искатьtoLowerCaseдля массивов вы можете искатьconcat, так далее.

Этот подход не является надежным, так как вы могли бы иметьobject случается, что у вас есть свойство с тем же именем, которое вы проверяете (хотя, если свойство, которое вы проверяете, это все, что вам нужно, то мы в основномутка печатать), но если вы знаете, что имеющееся у вас значение является примитивом, вы в хорошей форме, поскольку вы не можете назначать свойства примитивам (здесьнемного интересного чтения на эту тему).

Отказ от ответственности: я на самом деле не верю, что это хорошая идея и, возможно, она не очень удобна в обслуживании или переносима, но если вам просто нужно что-то быстрое для прототипа или очень ограниченного варианта использования, это разумный инструмент, чтобы иметь в своем поясе ,

Решение Вопроса

window, typeof, перечисления или статические методы не доступны в шаблоне. Доступны только члены класса компонента и конструкции языка машинописи.

Вы можете добавить вспомогательный метод к вашему компоненту, как

isNumber(val) { return typeof val === 'number'; }

и использовать его как

<label class='number' *ngIf='isNumber(obj[key])'>
 jarodsmk05 сент. 2018 г., 13:29
Просто обратите внимание, что это не рекомендуется по соображениям производительности, так как функция будет выполняться при каждом дайджесте.
 jarodsmk06 сент. 2018 г., 08:56
@ GünterZöchbauer Я сталкивался с некоторыми другими сообщениями SO об этом и думал об этом тоже, так как это не было упомянуто здесь. Добавлю еще один ответ, когда получу шанс просто на полноту
 Günter Zöchbauer08 апр. 2019 г., 08:43
@deadManN Эти проблемы с дайджестами полностью исчезли. Обнаружение изменений реализовано совершенно иначе, чем AngularJS. Существуют некоторые крайние случаи, например, когда значение изменяется, а затем возвращается к исходному значению (например, true -> false -> true), где Angular не распознает изменения, когда обнаружение изменений не вызывается вручную послеfalse, Это может вызвать проблемы в редких случаях, таких как флажок, когда обработчик события обновления отменяет изменение. Есть также несколько редких случаев, которые не покрываются NgZone автоматически и нуждаются вNgZone.run(...) быть вынужденным в зону Angulars.
 Günter Zöchbauer07 апр. 2018 г., 11:16
Это plannec, но еще не реализовано. Увидетьgithub.com/Microsoft/TypeScript/issues/2214, Комментарии показывают некоторые обходные пути
 deadManN08 апр. 2019 г., 08:24
я помню, у angularjs были проблемы савтоматический обновление дайджеста и области видимости, когда вы использовали функцию для таких вещей, как ng-if ... это решается с помощью Angular X .. или она все еще предпочитает вызывать функции только один раз?
 mdarefull07 апр. 2018 г., 11:09
Что делать, если у меня много типов и я хочу использовать ngSwitch. Является ли это возможным?
 Günter Zöchbauer05 сент. 2018 г., 13:33
@ N15M0_jk вы правы, это относится к каждому получателю и функциям, доступным из привязок. Для производительности всегда лучше назначать результат полю и связываться с этим полем. Это не всегда может быть необходимо. Если вы используете OnPush, это не проблема, поскольку обнаружение изменений выполняется гораздо реже.
 Pablo29 мая 2016 г., 16:40
Спасибо! Я создал этот метод, который должен возвращать так же, какtypeof в моем классе, чтобы решить! toType (obj) {return ({}). toString.call (obj) .match (/ \ s ([a-zA-Z] +) /) [1] .toLowerCase (); }

что это не будет работать в производстве, потому что имена функций сокращены. Безопаснее использовать что-то вроде:

foo instanceof FooClass

Но обратите внимание, что вы должны сделать это в компоненте / директиве, потому чтоinstanceOf недоступно в шаблонах:

// In your component
isFoo(candidate){
    return candidate instanceOf FooClass;
}

// in your template
{{isFoo(maybeFoo)}}

вы можете сравнить имя конструктора.

{{ foo.constructor.name === 'FooClass' }}

Подробная информация об этомВот.

 aron9forever13 мар. 2019 г., 15:23
По понятным причинам это не сработает в тех случаях, когда вам нужно проверить, что что-то на самом деле определено.(typeof thing !== 'undefined), Возможно, стоит упомянуть в ответе, может спасти других от ощущения глупости в течение нескольких секунд, если они не сразу примут это во внимание; даже через несколько лет после того, как это было опубликовано.
 tom05 мая 2019 г., 23:13
Важно: см. Комментарий Гейба Мартина-Демпси подсвязанный ответ почему это плохо для Angular и не будет работать на производстве.
 tom04 мая 2019 г., 01:51
@ aron9forever Если есть вероятность, что это может бытьundefinedДобавьте оператор безопасной навигации:foo?.constructor.
 benshabatnoam21 февр. 2019 г., 13:11
Ницца! спасибо за очень простой и элегантный ответ

Ваш ответ на вопрос