Pergunta

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"
Foi útil?

Solução

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.)

Outras dicas

You say that it's important that the model is shared. Is the model actually bound at another place? In your example MyModel is only used in MyForm.

When you call pub build --mode debug the generated JavaScript is quite readable. Maybe you can get some additional information trying to debug the JavaScript code.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top