dart-archive / polymer-dart

Polymer support for Dart
https://pub.dartlang.org/packages/polymer
BSD 3-Clause "New" or "Revised" License
181 stars 33 forks source link

Binding not updating #666

Open ErikGrimes opened 8 years ago

ErikGrimes commented 8 years ago

_mainapp.html

<dom-module id="main-app">
  <style>
    :host {
      display: block;
    }
  </style>

  <template>

      <recursive-item item="[[item]]"></recursive-item>

  </template>
</dom-module>

_mainapp.dart


@PolymerRegister('main-app')
class MainApp extends PolymerElement {

  @property
  RecursiveItem item;
  /// Constructor used to create instance of MainApp.
  MainApp.created() : super.created();

  ready(){
    set('item', _buildModel());
  }

_buildModel(){
  RecursiveModel model = new RecursiveModel();
  model.children.add( new RecursiveModel());
  model.other = new Other("root");
  model.children[0].other = new Other("child");
  return model;
}
}

_recursiveitem.html

<dom-module id="recursive-item">
  <style>
    :host {
      display: block;
    }
  </style>

  <template>
    <template is="dom-if" if="[[computeHasChildren(item)]]">
      root-if
      <div>property: [[item.other.name]]</div>
      <div>computed: [[computeName(item)]]</div>

      <recursive-item item="[[arrayItem(item.children.*,0)]]"></recursive-item>

    </template>

 <template is="dom-if" if="[[!computeHasChildren(item)]]">
      child-if
      <div>property: [[item.other.name]]</div>
      <div>computed: [[computeName(item)]]</div>
    </template>

  </template>
</dom-module>

_recursiveitem.dart

PolymerRegister('recursive-item')
class RecursiveItem extends PolymerElement {

  @property
  RecursiveModel item;

  RecursiveItem.created() : super.created();

  @reflectable
  bool computeHasChildren(RecursiveModel item){
    return item.children.isNotEmpty;
  }

  @reflectable
  arrayItem(change, index){
    return change['base'][index];
  }

  @reflectable
  computeName(RecursiveModel item){
    return item.other.name;
  }

}

expected

root-if
property: root
property: root
child-if
property: child
computed: child

actual

root-if
property: root
computed: root
child-if
property: 
computed: child
zoechi commented 8 years ago

In your MainApp class you have a property

@property
RecursiveItem item;

and assign a RecursiveModel to item in ready(). How is that supposed to work? Can you please add the source of RecursiveModel and the Other class?

ErikGrimes commented 8 years ago
  1. Set should trigger the bindings to related to item to update.
  2. Here's the model.
class RecursiveModel extends Object with JsProxy {
  @reflectable
  Other other;

  @reflectable
  List<RecursiveModel> children = [];

  @reflectable
  RecursiveModel single;

}

class Other extends Object with JsProxy {

  @reflectable
  String name;

  Other(this.name);

}
zoechi commented 8 years ago

What about the type mismatch between RecursiveItem vs RecursiveModel from my last comment?

ErikGrimes commented 8 years ago

Ah...didn't see that. I changed the type to RecursiveModel, but the property binding in the child still doesn't update.

ErikGrimes commented 8 years ago

The culprit is the array binding.

item="[[arrayItem(item.children.*,0)]]"

Passing a model straight through works. The array binding works in the sense that it passes the array element down to the child element, which is why the computed binding works, but I can't seem to trigger binding updates for it, not even by setting the item.other.name property in an observer.

  @reflectable
  handleItemChanged(RecursiveModel newItem, oldItem){
    new Future.delayed(new Duration(seconds:1),(){
      set('item.other.name',newItem.other.name);
    });
  }