How can I listen for changes to properties on objects inside a list, with polymer-dart?

Issue

I have a list of objects (for example, people), and I dynamically add and remove from the list. I want to run a query across the list when a certain property changes on any item in the list.

For example, I want to know if any object in the list has its “signedAgreement” property changed. I don’t want to manually attached listeners to each object, I just want to ask the list. How can I do this?

My code:

library my_element;

import 'package:polymer/polymer.dart';
import 'dart:html';
import 'models.dart';

@CustomTag("my-element")
class MyElement extends PolymerElement with ObservableMixin {
  final List people = toObservable([]); // observe adds/removes to the list
  final Person newPerson = new Person();

  // How can I know when to re-evaluate signedCount?

  int get signedCount => people.where((Person p) => p.signedAgreement).length;

  void save(Event e, var detail, Node target) {
    people.add(new Person.from(newPerson));
    newPerson.blank();
  }
}

And my model object looks like:

library models;

import 'package:polymer/polymer.dart';

class Person extends Object with ObservableMixin {
  @observable String name;
  @observable bool signedAgreement = false;

  Person();

  Person.from(Person other) {
    name = other.name;
    signedAgreement = other.signedAgreement;
  }

  blank() {
    name = '';
    signedAgreement = false;
  }
}

Solution

Enter: ListPathObserver!

Add this constructor:

  MyElement() {
    ListPathObserver observer = new ListPathObserver(people, 'signedAgreement');
    observer.changes.listen((_) => notifyProperty(this, const Symbol('signedCount')));
  }

Here, observer will fire when any person in people has its signedAgreement property changed.

Then, in the callback, we notify the observer system that it should go look at signedCount.

Answered By – Seth Ladd

Answer Checked By – Cary Denson (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *