3

I am trying to understand how observable getters work when they use other class instance properties:

When I bind the implicit getter/setter pair 'name' it updates in the input and in the div and everything is synced nicely.

However the explicit getter 'fullname' is not updating in the HTML. Is there a way to make that work (basically the 'fullname' in the element binding should update as well)?? Maybe I am missing a setter, but then again setter does not make sense here...

Very simple example to demonstrate:

test-element.html

<link rel="import" href="../../packages/polymer/polymer.html">
<polymer-element name="test-element">
  <template>
    <input value="{{ds.name}}">
    <div>{{ds.name}}</div>
    <div>{{ds.fullname}}</div>
  </template>
  <script type="application/dart" src="test1.dart"></script>
</polymer-element>

test-element.dart

import 'package:polymer/polymer.dart';
import 'package:popoli/sysmaster-settings.dart';

@CustomTag('test-element')
class TestElement extends PolymerElement {
  @observable VerySimpleTest ds;

  TestElement.created() : super.created() {
    ds = new VerySimpleTest()..name = 'Peter';
  }
}

ds.dart

class VerySimpleTest extends Observable {
  @observable String name = '';
  @observable String get fullname => 'Test: $name';
  VerySimpleTest() : super();
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Peter StJ
  • 2,297
  • 3
  • 21
  • 29

2 Answers2

3

You need to notify Polymer that a value has changed the getter depends on.

String set name(String val) {
  name = notifyPropertyChange(#fullname, name, val);
}

or this should work too

@ComputedProperty('Test: $name') String get fullname => 'Test: $name';

See http://japhr.blogspot.co.at/2014/08/the-polymerdart-computedproperty.html for more details.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    Also of interest, when you call notifyPropertyChange explicitly, you don't need to add the @observable annotations (and thus you don't need the transformer to run). See https://groups.google.com/a/dartlang.org/forum/#!topic/web/007Ij-l_hf4 – Jonas Kello Feb 05 '15 at 15:23
  • +Jonas Kello - copied from your Link: It's OK. But it might be better to have @observable. If someone is trying to enumerate the set of observable properties they can find yours too. It's just extra metadata though, so if your application does not enumerate properties like that, you can safely leave it off. ChangeNotifier does not care :) – Günter Zöchbauer Feb 05 '15 at 15:27
  • thank you, in the first way the symbol is used, but in the second the value, is this correct? so if the value is much more complex I still need to have it as it is in the param for the annotation? – Peter StJ Feb 05 '15 at 17:58
  • I haven't used the 2nd variant myself much yet and admit that I don't understand what's going on behind the scenes. I guess Polymer evaluates the expression and if the value changes it knows that bindings depending on the getter need to be updated. – Günter Zöchbauer Feb 05 '15 at 18:03
1

Some minor adaptations on Günter’s proposal make it work for me:

class VerySimpleTest extends Observable {
    String _name = '';
    //  @observable  // apparently, not even required
    String get name => _name;
    //  @observable  // apparently, not even required
    String get fullname => 'Test: $name';

    set name(String val) {
        String oldVal = _name;
        _name = notifyPropertyChange(#name, oldVal, val);
        _name = notifyPropertyChange(#fullname, oldVal, val);
    }
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Benjamin
  • 275
  • 2
  • 8