-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Custom element's 'created' constructor called twice #20197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I cannot repro 15844 but can repro this bug, so unlinking. cc @sigmundch. |
The root of the issue appears to be that the child element class (confusingly named MyParent in the repro, but the intention is clear) extends from PolymerElement, but has an extends attribute for 'my-parent'. document.registerElement validates the extends tag, but since that only gets the native element name, it is passed null for the extends tag (native element is HtmlElement). The second parent creation is occurring within Polymer.js during registration of the my-child element. |
This comment was originally written by @almstrand The initial sample code is updated below to:
warning: more than one Dart script tag in http://localhost:8080/index.html. Dartium currently only allows a single Dart script tag per document. pubspec.yaml name: myapp web/index.html <!DOCTYPE html> <my-parent>parent element</my-parent> <script type="application/dart">export 'package:polymer/init.dart';</script> web/my-parent.html <link rel="import" href="packages/polymer/polymer.html"> web/my-child.html <link rel="import" href="packages/polymer/polymer.html"> web/MyParent.dart import 'package:polymer/polymer.dart'; @CustomTag("my-parent") web/MyChild.dart import 'package:polymer/polymer.dart'; @CustomTag("my-child") This produces the same console output as in the original report, i.e.: parent created (:1) Per comment #3, I updated MyChild.dart as follows: web/MyChild.dart import 'MyParent.dart'; // <-- changed @CustomTag("my-child") And then the base class constructor is invoked trice! : parent created (:1) Assuming this implementation is correct, the issue seems fairly important as invoking a constructor more than once is bound to cause bugs due to initialization problems that may be hard to track down. |
Just to narrow things down, below is a slightly smaller and possibly more telling repro, https://gist.github.com/jakemac53/06adf5aca6c3a3aa1684. I am not adding any parent or child tags (only definitions), yet I still get a log from the parent. It seems that adding the extends="foo" causes an instance of the extended class to be created, at least temporarily. |
Ran across this in a test I was porting as well, it looks like ready() is also being fired on the extra element. |
Discovered the actual cause of this when investigating issue #21466. Whenever registering a custom element that extends from another element, dart:html creates an instance of the base element and compares its type to make sure you are actually extending that class. When registering a custom element in javascript, there is no such check. You can register an element which claims to extend 'input' with any arbitrary prototype. This seems pretty broken to me, since custom elements can have static state that is affected whenever a new element is created, and they can be potentially expensive to create (firing off ajax requests for example). |
Edit: It actually looks like this only happens when extending native html types, which is much safer. Polymer.js was creating instances of the base tag when trying to figure out if the element had been registered or not. We are now registering all dart custom elements with polymer so that it doesn't have to do that. |
Set owner to @jakemac53. |
This issue has been moved to dart-archive/polymer-dart#248. |
I had this same issue with an element (my-login), this was used inside my-menu element. This my-menu element was used twice. So this in turn, initializes my-login element twice also. I fixed the issue, by using conditional binding. Hope this helps someone. |
This issue was originally filed by @almstrand
The following is the minimal code I came up with which demonstrates the problem.
pubspec.yaml
=============================
name: myapp
dependencies:
polymer: ">=0.12.0-dev <0.12.0"
transformers:
entry_points: web/index.html
web/index.html:
=============================
<!DOCTYPE html>
<html>
<head>
<title>index</title>
<script src="packages/web_components/platform.js"></script>
<script src="packages/web_components/dart_support.js"></script>
</head>
<body>
<link rel="import" href="packages/polymer/polymer.html">
<!-- parent element -->
<polymer-element name="my-parent">
<script type="application/dart">
import 'package:polymer/polymer.dart';
@CustomTag("my-parent")
class MyParent extends PolymerElement {
MyParent.created() : super.created() {
print("parent created");
}
}
</script>
</polymer-element>
<!-- child element -->
<polymer-element name="my-child" extends="my-parent">
<script type="application/dart">
import 'package:polymer/polymer.dart';
@CustomTag("my-child")
class MyParent extends PolymerElement {
MyParent.created() : super.created() {
print("child created");
}
}
</script>
</polymer-element>
<my-parent>parent elment</my-parent>
<my-child>child element</my-child>
<script type="application/dart">export 'package:polymer/init.dart';</script>
</body>
</html>
Expected console log:
parent created (:1)
child created (:1)
Actual console log:
parent created (:1)
parent created (http://127.0.0.1:8080/packages/polymer/src/js/polymer/polymer.js:12)
child created (:1)
Reproduced in:
Dart SDK version: 1.5.3
Polymer package version: 0.12.0-dev
Operating system: Ubuntu 14.04 64-bit
Browser (if any): Dartium, version 36.0.1985.97 (280598)
The text was updated successfully, but these errors were encountered: