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

Я изучаю Angular2. У меня есть компонент с переменной, которая является объектом. Я повторяю поля объекта, и в зависимости от типа данных этой позиции мне нужно сделать другой компонент. В этом случае я хочу, чтобы tu отображал, что 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

Ответы

Ответ 1

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

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

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

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

<label class='number' *ngIf='isNumber(obj[key])'>

Ответ 2

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

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

Подробная информация об этом здесь.

Ответ 3

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

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

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

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

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

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

Ответ 4

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

foo instanceof FooClass

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

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

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