How to differentiate Dart types

122 views Asked by At

I have the following types:

class AddressEditor extends TextEditor {}
class TypeEditor extends TextEditor {}

I tried to identify the editors as such:

void validationErrorHandler( ValidationError e )
{
  var editor = e.editor;
  if( editor is AddressEditor )
   print( editor.runtimeType.toString() ) // prints TextEditor

  if( editor is TypeEditor )
   print( editor.runtimeType.toString() ) // prints TextEditor
}

If I use mirrors

import 'dart:mirrors'; 

getTypeName(dynamic obj) 
{
  return reflect(obj).type.reflectedType.toString();
}

void validationErrorHandler( ValidationError e )
{
  var editor = e.editor;
  if( editor is AddressEditor )
   print( getTypeName( editor ) ) // prints TextEditor

  if( editor is TypeEditor )
   print( getTypeName( editor ) ) // prints TextEditor
}

Why is the editor type TypeEditor and AddressEditor not being identified? Yes, I know that either is a TextEditor, but is there any way to identify the TypeEditor or the AddressEditor in Dart.

I need to make these identification to work with the result of the validation.

Thanks

1

There are 1 answers

5
Günter Zöchbauer On BEST ANSWER

UPDATE

It turns out that TextEditor has a method newInstance() which is called to acquire new editor instances by BWU Datagrid (basically TextEditor is a factory and the implementation in one).

Because TypeEditor and AddressEditor don't override this method, internally pure TextEditor instances are created.

To get the desired behavior you need to override newInstance and implement the constructor used by this method. Because the constructor in TextEditor is private it can not be reused and needs to be copied (I'll reconsider this design). The first two lines of the copied constructor need to be adapted a little.

The AddressEditor would then look like

class AddressEditor extends TextEditor {
  AddressEditor() : super();

  @override
  TextEditor newInstance(EditorArgs args) {
    return new AddressEditor._(args);
  }

  AddressEditor._(EditorArgs args) {
    this.args = args;
    $input = new TextInputElement()
      ..classes.add('editor-text');
    args.container.append($input);
    $input
      ..onKeyDown.listen((KeyboardEvent e) {
      if (e.keyCode == KeyCode.LEFT || e.keyCode == KeyCode.RIGHT) {
        e.stopImmediatePropagation();
      }
    })
      ..focus()
      ..select();
  }
}

The TypeEditor is the same just a different class and constructor name.

ORIGINAL

I'm pretty sure that the above example with is works fine and that the problem lies somewhere else (that these values are not AddressEditors or TypeEditors but just TextEditors.

class TextEditor {}

class AddressEditor extends TextEditor {}
class TypeEditor extends TextEditor {}

void main() {
  check(new AddressEditor());
  check(new TypeEditor());
  check(new TextEditor());
}

void check(TextEditor editor) {
  if(editor is AddressEditor) print('AddressEditor: ${editor.runtimeType}');
  if(editor is TypeEditor) print('TypeEditor: ${editor.runtimeType}');
  if(editor is TextEditor) print('TextEditor: ${editor.runtimeType}');
}

output

AddressEditor: AddressEditor
TextEditor: AddressEditor

TypeEditor: TypeEditor
TextEditor: TypeEditor

TextEditor: TextEditor