是否有内置功能可以在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。
无论如何我在飞镖中实现这种模式吗?
答案 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_stream和event_source可以简化此任务。