如何在Dart中实现可事件类型

时间:2013-05-09 13:55:27

标签: events design-patterns dart

是否有内置功能可以在dart中创建可事件类型?

在我的Javascript应用程序中,我使用名为Eventable的类来提供以下功能:

var dog = new Dog() //where Dog inherits from Eventable
var cat = new Cat() //where Cat inherits from Eventable

//use 'on' to listen to events
cat.on(dog, 'bark', cat.runaway); //assuming Cat has a method runaway on its prototype

//use fire to launch events
dog.fire({type: 'bark'});  //this causes cat.runaway(event); to be called

javascript中一个非常常见的模式,我喜欢它,因为它帮助我保持src中的对象和我的想法。

使用on方法创建new EventContract,其中包含基于所有者(上面为cat),客户端(上面为dog),类型({{上面的1}}和函数(上面的'bark')。这个唯一键允许我确保没有创建重复的cat.runaway,但更重要的是它允许我保持一个对象具有的所有EventContract的易于查找的集合,这样我就可以拨打:

EventContract

并且cat.dispose(); 的所有事件合同都将被销毁,因此我确信所有对cat的外部引用都已被删除,而cat现在可以进行GC。

但是我发现很难在Dart中实现这个功能,因为执行类似:cat的操作会导致生成一个新函数来包含cat.on(dog, 'bark', cat.runaway);,并且唯一可以获得的唯一键是dart中的标准函数对象是它的hashCode,但这意味着我可以回忆(){cat.runaway();}并创建一个新的cat.on(dog, 'bark', cat.runaway);,因为它创建了另一个唯一的闭包,而不是处理对原始函数的引用,如发生在javascript。

无论如何我在飞镖中实现这种模式吗?

1 个答案:

答案 0 :(得分:7)

通常,您应该使用Stream作为惯用方式在Dart中提供一系列事件。此外,最好在源代码上声明事件(例如onBark而不是on['bark']。这样的事情应该让你开始:

class Dog {
  var _barkController = new StreamController();
  Stream get onBark => _barkController.stream.asBroadcastStream();
  void bark() => _barkController.add("woof");
}

class Cat {
  void runaway() => print("cat running");
}

void main() {
  var dog = new Dog();
  var cat = new Cat();

  // listen returns subscription object which you can use to unsubscribe
  var sub = dog.onBark.listen((event) => cat.runaway()); 

  dog.bark();  // prints 'cat running'
  sub.cancel();
  dog.bark();  // doesn't print anything
}

如果您希望动态声明事件,可以使用以下内容:

  var sub = dog.on['bark'].listen((event) => cat.runaway()); 
  // in this case `on` is a property of some Events type which overrides
  // operator[] to return appropriate Stream

已经存在类似的Events class,用于在DOM元素上提供浏览器事件。

此外,社区图书馆event_streamevent_source可以简化此任务。