Functionality in parent class needs to detect chan

2019-02-25 17:09发布

问题:

I am trying to find a way for this parent "Persistent" class to add functionality so that the "changed" property becomes true whenever any property of the child object is changed.

class Persistent {
  bool changed = false;

  Persistent() {
    print('Something should be added here to make this work.');
  }
}

class Child extends Persistent {
  num number = 1;
  // Nothing should be done in this class to make this work.
}

main() {
  Child item = new Child();
  item.number = 2;
  assert(item.changed == true); //fails
}

Requirement: The goal is for this to be transparent to the Child class. The functionality to detect changes must not exist in the Child class, only inside of the Persistent class.

Thank you Dart experts for your help! I look forward to hearing from you.

Here is the work in progress to get this working:

import 'dart:io';
import 'dart:async';
import 'dart:convert';
import 'package:observe/observe.dart';

class Persistent extends Object with ChangeNotifier {
  bool changed = false;

  Persistent() {
    this.changes.listen((List<ChangeRecord> record) => changed = false);
    //this.changes.listen((List<ChangeRecord> record) => changed = true); //Same exception
  }
}

class Child extends Persistent {
  @observable num number = 1;
  // Nothing should be done in this class to make this work.
}

main() {
  Child item = new Child();
  item.number = 2;
  assert(item.changed == true);
}

The above gives me the following exception:

Unhandled exception:
'file:///home/david/Dropbox/WebDevelopment/DODB/source/DODB/bin/dodb.dart': Failed assertion: line 22 pos 10: 'item.changed == true' is not true.
#0      main (file:///home/david/Dropbox/WebDevelopment/DODB/source/DODB/bin/dodb.dart:22:10)
#1      _startIsolate.isolateStartHandler (dart:isolate-patch/isolate_patch.dart:216)
#2      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:124)

回答1:

You can use the ChangeNotifier class like shown in the answers to this question

  • Observe package from polymer dart
  • How to use Dart ChangeNotifier class?
    see also
  • https://api.dartlang.org/apidocs/channels/be/dartdoc-viewer/observe/observe.ChangeNotifier
  • https://api.dartlang.org/apidocs/channels/be/dartdoc-viewer/observe/observe.Observable

Another attempt is to use reflection but this is discouraged especially in the browser. The above solution uses reflection too but as far as I know the Smoke transformer generates code that replaces the reflective code when you run pub build.

edit

Only after a call to Observable.dirtyCheck(); a change detection is initiated (for all observable instances).

import 'package:observe/observe.dart';

class Persistent extends Observable {
  bool changed = false;

  Persistent() : super() {
    changes.listen((e) => changed = true);
  }
}

class Child extends Persistent {
  @observable num number = 1;
}

main() {
  Child item = new Child();
  item.number = 2;
  Observable.dirtyCheck();
  assert(item.changed == true);
}


标签: dart