父类中的功能需要检测子类属性的更改

时间:2014-08-04 04:21:15

标签: dart

我正在尝试为这个父“Persistent”类找到一种方法来添加功能,以便只要更改子对象的任何属性,“changed”属性就会变为true。

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
}

要求:目标是使其对Child类透明。检测更改的功能必须不存在于Child类中,只能存在于Persistent类中。

感谢Dart专家的帮助!我期待着您的回复。

以下是正在进行的工作:

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);
}

上面给出了以下例外情况:

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 个答案:

答案 0 :(得分:2)

您可以使用此问题的答案中显示的ChangeNotifier

另一种尝试是使用反射,但这是不鼓励的,尤其是在浏览器中。 上面的解决方案也使用反射,但据我所知,Smoke变换器生成的代码在您运行pub build时替换了反射代码。

修改

仅在调用Observable.dirtyCheck();后才启动更改检测(对于所有可观察的实例)。

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);
}