What is the correct way to use a model in polymer element when model class is defined in imported packaged library?
I believe I did it correct (based on more articles e.g. How to subscribe to change of an observable field).
It works in DARTIUM but when it's built to JS it doesn't. I can't really figure out what's happening there, see logs down. Listeners and value in field behave strange.
Key factors: my model class is packaged in shared library for some reasons and have to use my input element
What am I missing? Or is there a bug in dart2js?
FILES and LOGS
testlib.dart (just a model in packaged library, not a part of polymer app):
library testlib;
import 'package:observe/observe.dart';
class MyModel extends Object with Observable{
@observable String foo;
String toString(){
return "MyModel[foo:$foo]";
}
}
And in polymer app we have:
all_elements.dart (model is imported using package:...)
library test;
import 'package:polymer/polymer.dart';
import 'package:testlib/testlib.dart'; //!!!! note this is important, I need shared model
@CustomTag('my-input')
class MyInput extends PolymerElement {
@published String value;
valueChanged(oldValue){
print('text changed from "$oldValue" to "$value"');
}
MyInput.created() : super.created();
}
@CustomTag('my-form')
class MyForm extends PolymerElement {
@observable MyModel model = new MyModel();
modelChanged(oldValue){
print('text changed from "$oldValue" to "$model"');
}
MyForm.created() : super.created();
void ready(){
model.changes.listen((changes){
print('model properties changed $changes');
});
}
}
and all_elements.html
<polymer-element name="my-input">
<template>
<p>My Input</p>
<input type="text" value="{{value}}"/>
</template>
</polymer-element>
<polymer-element name="my-form">
<template>
<my-input value="{{model.foo}}"></my-input>
</template>
</polymer-element>
<script type="application/dart" src="all_elements.dart"></script>
and app entry point: testapp.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test app</title>
<link rel="import" href="all_elements.html">
<script type="application/dart">export 'package:polymer/init.dart';</script>
<script src="packages/browser/dart.js"></script>
</head>
<body>
<my-form></my-form>
</body>
</html>
LOGS:
Everything works fine till it's built to JS. When trying to write word "hello" to input I get:
DARTIUM - OK
text changed from "null" to "h"
model properties changed [#<PropertyChangeRecord Symbol("foo") from: null to: h>]
text changed from "h" to "he"
model properties changed [#<PropertyChangeRecord Symbol("foo") from: h to: he>]
text changed from "he" to "hel"
model properties changed [#<PropertyChangeRecord Symbol("foo") from: he to: hel>]
text changed from "hel" to "hell"
model properties changed [#<PropertyChangeRecord Symbol("foo") from: hel to: hell>]
text changed from "hell" to "hello"
model properties changed [#<PropertyChangeRecord Symbol("foo") from: hell to: hello>]
JavaScript - PROBLEM (type "hello" - get "hel", type "mystery" - get "mytr" )
text changed from "null" to "h"
model properties changed [#<PropertyChangeRecord Symbol("foo") from: null to: h>]
text changed from "h" to "he"
text changed from "he" to "h"
model properties changed [#<PropertyChangeRecord Symbol("foo") from: h to: he>]
text changed from "h" to "hl"
text changed from "hl" to "he"
model properties changed [#<PropertyChangeRecord Symbol("foo") from: he to: hl>]
text changed from "he" to "hel"
text changed from "hel" to "hl"
model properties changed [#<PropertyChangeRecord Symbol("foo") from: hl to: hel>]
text changed from "hl" to "hlo"
text changed from "hlo" to "hel"
The js generated by pub build is quite different when there is a polymer transformer in the dependent package vs. not, particularly the js code that is involved in detecting and propagating observable changes.
Try adding a polymer transformer to the import package pubspec:
name: testlib
dependencies:
browser: any
observe: any
polymer: any
transformers:
- polymer:
entry_points:
(Note that no actual entry_points value is required, just the presence of the polymer transformer entry.)