Reputation: 12293
How come this example:
import "dart:html";
class SubMenuElement extends DivElement {
SubMenuElement() {
print("my element created");
}
}
Gives the error:
Internal error: 'file.dart': error: line x pos y: unresolved implicit call to super constructor 'DivElement()'
SubMenuElement() {
^
What does the error message mean and how would a working example be?
Upvotes: 3
Views: 577
Reputation:
You can declare a subclass of DivElement as follows:
import 'dart:html';
class MyDiv extends DivElement {
factory MyDiv() => new Element.tag('div', 'my-div');
MyDiv.created() : super.created();
}
The factory constructor is not required, but it is convenient if you want to construct instances imperatively.
You must then register your custom element with a document before you can instantiate it:
main() {
document.register('my-div', MyDiv, extendsTag: 'div');
document.body.append(new MyDiv()..text = 'Hello');
}
The above will work in Dartium, or any browser that natively implements the Custom Elements specification (Chrome 33+ for example). To run in another browser, you will need to add the custom element polyfill. You can add this to your pubspec:
dependencies:
custom_element: '>=0.9.0'
...
And after running pub get
you can add the polyfill script to your html:
<body>
<script src="packages/custom_element/custom-elements.min.js"></script>
...
</body>
Upvotes: 2
Reputation: 3832
The error message means that the default constructor DivElement()
doesn't exist. This constructor is implicitly called because you didn't specify another constructor to be called.
That being said, DivElement can't be subclassed directly. But you can simulate that behaviour by implementing DivElement instead of extending it and delegating every call:
class MyDivElement implements DivElement {
DivElement _delegate;
MyDivElement() {
_delegate = new DivElement();
// whatever else should happen in your constructor
}
// For best performance, every member SHOULD be implemented explicitly.
String get text => _delegate.text;
Node get parentNode => _delegate.parentNode;
ShadowRoot get shadowRoot => _delegate.shadowRoot;
// But DivElement has a lot of members.
// Unused or rarely used members could also be delegated with reflection.
noSuchMethod(Invocation invocation) => reflect(_delegate).delegate(invocation);
}
Upvotes: 2
Reputation: 658263
DivElement doesn't have a default constructor. You need to add a named constructor and a call to the named constructor on super.
SubMenuElement.created() : super.created();
If you derive a DOM element you should add with Polymer
import 'dart:html';
import 'package:polymer/polymer.dart';
class SubMenuElement extends DivElement with Polymer {
SubMenuElement.created() : super.created();
}
You haven't stated that you want to create a Polymer element but you can use custom elements only with Polymer, so I assumed you do.
Upvotes: 3