Проверить тип объекта в Polymer Element

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

<polymer-element name="my-element">
<template>
    {{model.runtimeType}} <!-- sanity check -->
    {{model.commonProperty}}
    <template if="{{model is Foo}}">
      {{model.fooSpecificProperty}}
    </template>
    <template if="{{model is Bar}}">
      {{model.barSpecificProperty}}
    </template>
</template>
<script type="application/dart" src="my-element.dart"></script>
</polymer-element>

Я обнаружил, что оба шаблона if отображаются, как будто оба model is Foo и model is Bar возвращают true. Я вижу, что для каждого типа модели {{model.runtimeType}} печатает Foo и Bar соответственно.

Я также пытался изменить условия if на другие вещи, такие как {{model.runtimeType.toString() == 'Foo'}}, но я не могу найти правильное условие для правильной сортировки типов моих моделей.

Каков правильный способ обнаружения и фильтрации в элементе Dart Polymer на основе типа объекта?

РЕДАКТИРОВАТЬ: Также обратите внимание, что и {{model is Foo}}, и {{model is! Foo}}, кажется, возвращают true как условное выражение при использовании в Polymer, но работают, как и ожидалось, внутри файла .dart.


person Michael Fenwick    schedule 16.09.2014    source источник


Ответы (3)


Здесь важно не использовать toString(), так как он не будет работать при использовании dart2js с минификацией. Как и в других предложениях, вот две идеи, которые должны работать даже с запутыванием/минификацией.

<polymer-element name="x-tag">
<template>
    <!-- idea #1 -->
    <template if="{{model.runtimeType == fooType}}"> ...

    <!-- idea #2 -->
    <template if="{{isFoo}}"> ...

а также

@CustomTag(x-tag)
class XTag extends PolymerElement {
  // idea #1
  Type get fooType => Foo;

  // idea #2
  @observable bool isFoo;
  @ObserveProperty('model')
  updateIsFoo() { isFoo = model is Foo; }

}
person Siggi Cherem    schedule 18.09.2014

Проблема в том, что Foo/Bar (типа Type не распознаются/не доступны в выражениях Polymer, поэтому is или is! не могут работать.

model.runtimeType.toString() == 'Bar'

хотя должно работать. Я расследую.

То, что я получил, это:

on my-element

String asString(value) {
  return value.runtimeType.toString();
} 
  <template if="{{asString(model) == 'Foo')}}">
    {{model.fooSpecificProperty}}
  </template>
  <template if="{{asString(model) == 'Bar'}}">
    {{model.barSpecificProperty}}
  </template>

также работает

class Base {
  String commonProperty = 'common';

  @override
  String toString() => runtimeType.toString();
}
  <template if="{{model.toString() == 'Foo')}}">
    <div style="border: solid 1px red;">{{model.fooSpecificProperty}}</div>
  </template>
  <template if="{{model.toString() == 'Bar'}}">
    <div style="border: solid 1px green;">{{model.barSpecificProperty}}</div>
  </template>
person Günter Zöchbauer    schedule 17.09.2014
comment
Я полагаю, что это имеет смысл в отношении Foo/Bar, хотя мне интересно, почему и is, и is! оцениваются как истинные (хотя мне кажется, что они должны оцениваться как ложные или, что еще лучше, выдавать полезную ошибку. - person Michael Fenwick; 17.09.2014
comment
Ты прав. И это должно работать {{model.runtimeType.toString() == 'Foo'}} - person Günter Zöchbauer; 17.09.2014
comment
странный model.runtimeType.toString(), используемый для проверки работоспособности, ничего не печатает. - person Günter Zöchbauer; 17.09.2014
comment
Рад видеть отчеты об ошибках. Я не был уверен, что я делаю что-то не так, или у Polymer Dart возникли проблемы. Рад узнать, что это был не только я. - person Michael Fenwick; 17.09.2014
comment
Обратите внимание, что model.runtimeType.toString() может измениться при минификации/обфускации (подробности см. в описании ошибки) - person Siggi Cherem; 19.09.2014

В свете ошибки Polymer https://code.google.com/p/dart/issues/detail?id=20980, кажется, что сейчас лучший способ сделать это — обходной путь. Самый чистый обходной путь, который я смог найти, это

мой-element.html

<polymer-element name="my-element">
<template>
    {{model.runtimeType}} <!-- sanity check -->
    {{model.commonProperty}}
    <template if="{{model.type == 'Foo'}}">
      {{model.fooSpecificProperty}}
    </template>
    <template if="{{model.type == 'Bar'}}">
      {{model.barSpecificProperty}}
    </template>
</template>
<script type="application/dart" src="my-element.dart"></script>
</polymer-element>

model_superclass.dart

abstract class ModelSuperclass {
  var commonProperty;
  String get type => this.runtimeType.toString();
}

В будущем, когда ошибка будет устранена, лучшим способом добиться этого будет использование

<template if="{{model.runtimeType.toString() == 'Foo'}}">
person Michael Fenwick    schedule 17.09.2014