Search code examples
dartdart-polymercustom-element

How to programmatically add extended LIElement in Polymer Dart?


I am wondering how to add custom element programmatically in dart?

My Code is :-

File: todoitem.html

<!-- import polymer-element's definition -->
<link rel="import" href="packages/polymer/polymer.html">

<polymer-element name="my-li" extends="li">
  <style>
      :host(:hover){
      color: red;
    }
  </style>
  <script type="application/dart" src="todoitem.dart"></script>
</polymer-element>

File: todoitem.dart:-

import 'package:polymer/polymer.dart';
import "dart:html" as html;

import 'package:logging/logging.dart';

final Logger _widgetlogger = new Logger("todo.item");

@CustomTag('my-li')
class MyListElement extends html.LIElement with Polymer, Observable {

  factory MyListElement() => new html.Element.tag('li', 'my-li');

  MyListElement.created() : super.created() {
    polymerCreated();
  }

  @override
  void attached() {
    super.attached();
    _widgetlogger.info("todoitem attached");
  }

  @override
  void detached() {
    super.detached();
    _widgetlogger.info("todoitem detached");
  }

}

File: todowidget.html

<!-- import polymer-element's definition -->
<link rel="import" href="packages/polymer/polymer.html">

<polymer-element name="todo-widget" attributes="title">
  <template>
    <style>
    :host(.colored){
      color: blue;
    }
    </style>
    <div>
      <h1>{{title}}</h1>
      <div>
        <input id="inputBox" placeholder="Enter Todo item" on-change="{{addToList}}">
        <button id="deleteButton" on-click="{{deleteAll}}">Delete All</button>
      </div>
      <ul id="todolist">
      </ul>
    </div>
  </template>
  <script type="application/dart" src="todowidget.dart"></script> 
</polymer-element>

Corresponding Dart Script:-

import 'package:polymer/polymer.dart';
import "dart:html" as html;
import "todoitem.dart";

import 'package:logging/logging.dart';

final Logger _widgetlogger = new Logger("todo.widget");

@CustomTag('todo-widget')
class TodoWidget extends PolymerElement {

  @published String title;
  html.InputElement todoInput;
//  html.ButtonElement deleteButton;
  html.UListElement todolist;

  @override
  void attached() {
    super.attached();
    todolist = $["todolist"];
    todoInput = $["inputBox"];
  }

  TodoWidget.created() : super.created() {
    //This can go into template!!!
    if (title == null) {
      title = "My Todo App";
    }
    ;
  }

  void deleteAll(html.Event e, var detail, html.Node target) {
    _widgetlogger.info("All items deleted");
    todolist.children.clear();
//    print("Clicked");
  }

  void addToList(html.Event e, var detail, html.Node target) {
    _widgetlogger.info("Item added");
    MyListElement li = new MyListElement();
    li
        ..text = todoInput.value
        ..classes.add("todoitem")
        ..onClick.listen((e) => e.target.remove());
    todolist.children.add(li);
    todoInput.value = "";
  }
}

It fails with following error:-

> 2014.10.29 15:10:32.758   todo.widget [INFO]: Item added (:1) Exception: Uncaught Error: type 'LIElement' is not a subtype of type
> 'MyListElement' of 'function    result'. Stack Trace:
> #0      MyListElement.MyListElement (http://localhost:8081/todowidget.dart:11:34)
> #1      addToList (http://localhost:8081/todowidget.dart:62:28)
> #2      Function.apply (dart:core-patch/function_patch.dart:28)
> #3      GeneratedObjectAccessorService.invoke (package:smoke/static.dart:149:28)
> #4      invoke (package:smoke/smoke.dart:43:41)
> #5      HtmlElement&Polymer.dispatchMethod (package:polymer/src/instance.dart:1054:19)
> #6      BindingDelegate&PolymerEventBindings.getEventHandler.<anonymous
> closure> (package:polymer/src/events.dart:82:32)
> #7      _RootZone.runUnaryGuarded (dart:async/zone.dart:1089)
> #8      _RootZone.bindUnaryCallback.<anonymous closure> (dart:async/zone.dart:1118)
> #9      BindingDelegate&PolymerEventBindings.prepareEventBinding.<anonymous
> closure>.<anonymous closure> (package:polymer/src/events.dart:101:67)

I am wondering how to add custom element programmatically in dart?


Solution

  • Edit

    Seems your file todowidget.html needs an import for my_li.html

    <link rel="import" href="packages/polymer/polymer.html">
    <link rel="import" href="myli.html">
    <polymer-element name="todo-widget" attributes="title">
    

    Old

    There were still an issue open about missing support for more than one element class per library.

    Try to split the Dart script into two files (one per Polymer element).