vue 侦听器侦听对象属性

听一个可观察的实例并对它的变化做出React很有趣。 做一些必要的事情来打断或结束这种聆听会变得很有趣。 让我们看看问题的根源和解决方法。

总览

这篇文章将首先讨论这种情况,然后再讨论常见的方法和问题所在。 然后,它将提供解决大多数问题的简单抽象。

尽管示例使用Java,但许多其他语言也存在缺陷。 提出的解决方案可以应用于所有面向对象的语言。 那些懒于自己在Java中实现抽象的人可以使用LibFX

情况

由Ky Olsen在CC-BY 2.0下发布 。

假设我们想听听属性值的变化。 这很简单:

不支持删除的简单案例

private void startListeningToNameChanges(Property<String> name) {name.addListener((obs, oldValue, newValue) -> nameChanged(newValue));
}

现在假设我们要在特定间隔内中断监听或完全停止监听。

保持参考

解决此问题的最常用方法是保留对侦听器的引用,并保留对周围属性的引用。 根据具体的用例,实现会有所不同,但是它们都可以归结为以下形式:

默认方式删除侦听器

private Property<String> listenedName;
private ChangeListener<String> nameListener;...private void startListeningToNameChanges(Property<String> name) {listenedName = name;nameListener = (obs, oldValue, newValue) -> nameChanged(newValue);listenedName.addListener(nameListener);
}private void stopListeningToNameChanges() {listenedName.removeListener(nameListener);
}

尽管这看起来不错,但我确信这实际上是一个糟糕的解决方案(尽管是默认解决方案)。

首先,额外的引用使代码混乱。 很难让他们表达出为什么要留在身边的意图,因此它们降低了可读性。

其次,它们通过向类添加新的不变式来增加复杂度:该属性必须始终是添加了侦听器的属性。 否则,对removeListener的调用将无提示地执行任何操作,并且在将来的更改时仍将执行该侦听器。 放开这可能是讨厌的。 如果类很短,则坚持不变性是容易的,但如果变得越来越复杂,则可能成为问题。

第三,引用(特别是该属性的引用)邀请与它们进行进一步的交互。 这可能不是故意的,但没有任何办法阻止下一个开发人员继续这样做(请参阅第一点)。 如果有人确实开始对该物业进行操作,第二点将成为非常现实的风险。

这些方面已经使它不能成为默认解决方案。 但是还有更多! 在许多类中必须这样做会导致代码重复。 最后,上面的实现包含一个竞争条件。

侦听器句柄

大多数问题来自直接在需要中断/结束侦听的类中处理可观察对象和侦听器。 这是不必要的,所有这些问题都可以通过一个简单的抽象来解决: ListenerHandle

ListenerHandle

public interface ListenerHandle {void attach();void detach();
}

ListenerHandle保留对可观察对象和侦听器的引用。 在调用attach()detach()它会将侦听器添加到可观察对象或将其删除。 为了将此语言嵌入语言,当前将侦听器添加到可观察对象的所有方法都应返回该组合的句柄。

现在剩下要做的就是为所有可能的情况实际实现句柄。 或者说服那些开发您喜欢的编程语言的人来做。 这留给读者练习。

注意,这解决了上面提到的所有问题,除了争用条件之外。 有两种方法可以解决此问题:

  • 处理实现可能本质上是线程安全的
  • 可以实现一个同步装饰器

LibFX中的ListenerHandles

作为Java开发人员,您可以使用LibFX ,它支持三个级别的侦听器句柄。

功能了解ListenerHandles

添加侦听ListenerHandle时, LibFX的所有可实现此功能而不会与Java API冲突的功能都会返回ListenerHandle

以WebViewHyperlinkListener为例:

将“ ListenerHandle”获取到“ WebViewHyperlinkListener”

WebView webView;ListenerHandle eventProcessingListener = WebViews.addHyperlinkListener(webView, this::processEvent);

JavaFX实用程序

由于LibFX与JavaFX有紧密的联系(可能会想到!),它提供了一个实用程序类,该类将侦听器添加到可观察对象并返回句柄。 这适用于JavaFX中存在的所有可观察/侦听器组合。

例如,让我们看一下ObservableValue<T> / ChangeListener<? superT>的组合ChangeListener<? superT> ChangeListener<? superT>

'ListenerHandles'中的一些方法

public static <T> ListenerHandle createAttached(ObservableValue<T> observableValue,ChangeListener<? super T> changeListener);public static <T> ListenerHandle createDetached(ObservableValue<T> observableValue,ChangeListener<? super T> changeListener);

ListenerHandleBuilder

在所有其他情况下,即对于上面未涵盖的任何可观察/侦听器组合,可以使用构建器来创建手柄:

为自定义类创建“ ListenerHandle”

// These classes do not need to implement any special interfaces.
// Their only connection are the methods 'doTheAdding' and 'doTheRemoving',
// which the builder does not need to know about.
MyCustomObservable customObservable;
MyCustomListener customListener;ListenerHandles.createFor(customObservable, customListener).onAttach((obs, listener) -> obs.doTheAdding(listener)).onDetach((obs, listener) -> obs.doTheRemoving(listener)).buildAttached();

React式编程

尽管这不是关于React式编程的文章 ,但仍应提及。 查看ReactiveX (用于许多语言,包括Java,Scala,Python,C ++,C#和更多语言)或ReactFX (或此介绍性文章 )以了解一些实现。

反射

我们已经看到,从可观察对象中删除侦听器的默认方法会产生许多危害,需要避免。 侦听器句柄抽象提供了解决许多问题的干净方法,而LibFX提供了一种实现。

翻译自: https://www.javacodegeeks.com/2015/01/dont-remove-listeners-use-listenerhandles.html

vue 侦听器侦听对象属性

vue 侦听器侦听对象属性_不删除侦听器–使用ListenerHandles相关推荐

  1. java类向拦截器传值_MyBatis拦截器:给参数对象属性赋值的实例

    该拦截器的作用:在进行增加.修改等操作时,给数据模型的一些通用操作属性(如:创建人.创建时间.修改人.修改时间等)自动赋值. 该实现是在dao层拦截,即存入db前最后一层.后经分析,不是很合理,改为在 ...

  2. js delete删除对象属性,delete删除不了变量及原型链中的变量

    js delete删除对象属性,delete删除不了变量及原型链中的变量 一.delete删除对象属性 function fun(){this.name = 'gg';}var obj = new f ...

  3. maya对象属性_Maya2014全面使用手册_了解每粒子属性和每对象属性_软件教程_资源库...

    摘要:Maya2014全面使用手册_了解每粒子属性和每对象属性_软件教程_资源库 相关视频教程学习推荐: 造型设计<鹫>造型上色完整流程[实名认证] 5,777人在学 总时长:27h 可以 ...

  4. 对象存储HTML自定义属性,设置对象属性_对象存储服务 OBS_SDK参考_Node.js_上传对象_华为云...

    开发过程中,您有任何问题可以在github上提交issue,或者在华为云对象存储服务论坛中发帖求助.接口参考文档详细介绍了每个接口的参数和使用方法. 您可以在上传对象时设置对象属性.对象属性包含对象长 ...

  5. 遍历对象属性_细说JS遍历对象属性的N种方法

    本人详细介绍了JS遍历对象N种方法,欢迎关注收藏. 遍历对象属性有五种方法,下图为一个场景对比图. 可以注意到两点: 只有for ... in 才可以遍历原型链属性,且只能遍历可枚举属性. Objec ...

  6. maya对象属性_了解每粒子属性和每对象属性

    可以将两种类型的属性动态添加到"粒子形状"(particle shape)节点: 每粒子 每对象 每粒子属性允许您分别设定对象的每个粒子的属性值.每对象属性允许您通过单个值整体设定 ...

  7. 遍历java对象属性_[Java教程]遍历对象属性

    [Java教程]遍历对象属性 0 2016-09-12 13:00:03 初始化对象:var person = function(name){ this._name = name;}var grand ...

  8. java删除对象属性_javascropt理解删除对象属性,防止内存泄漏

    delete运算符可以删除对象的属性,它的操作数应当是一个属性访问表达式, var book={ "author":"yang", "main tit ...

  9. 如何使用Vue.js中的set设置对象属性值

    1.问题背景 使用vue初始化一个对象v,并在data中初始化一个空对象obj,然后使用Vue.set()给对象obj添加属性 2.实现源码 <!DOCTYPE html> <htm ...

最新文章

  1. C#三种判断数据库中取出的字段值是否为空(NULL) 的方法
  2. 二十四、Struts2中的UI标签
  3. 如何修改路由器和交换机的密码
  4. [Angular 依赖注入详谈] Angular Module Providers几种类型的实现源代码具体位置
  5. gbdt 算法比随机森林容易_随机森林与GBDT
  6. ElasticSearch Java SpringBoot根据时间范围分组求和
  7. 如何在linux上创建数据库,在LINUX平台上手动创建数据库(oracle 10g)
  8. Linux 新加一块硬盘,添加到已有逻辑卷扩容
  9. 水泵综合性能测试系统软件,水泵综合性能测试系统
  10. Git-第一篇认识git,核心对象,常用命令
  11. matlab 三维图形改变线宽,用PANDAS改变线宽绘制三维线图
  12. 服务器网页上传附件按钮无法使用怎么解决,IE上传附件无法点击确定按钮的具体处理方法...
  13. Word转PDF方法怎么转?这三种Word转PDF方法你得知道
  14. 什么是IDOC,以及IDOC的步骤_小七_新浪博客
  15. win10关闭快速启动_关闭Win10中这七个不必要的服务,解决电脑卡顿问题。
  16. linux 服务器搭建opvn
  17. Lens5 指南:专为Kubernetes人员设计的IDE
  18. 微信H5、公众号开发,域名重定向
  19. Linux tar/rpm/yum命令软件安装
  20. python:在Windows上使用 Python

热门文章

  1. P1613-跑路【Floyd,倍增】
  2. 2019纪中暑假游记+总结
  3. jzoj3461-小麦亩产一千八【斐波那契数列】
  4. 【DP】和谐的奶牛(jzoj 1750)
  5. Sentinel(十一)之黑白名单控制
  6. sleep( ) 和 wait( ) 的这 5 个区别,你知道几个
  7. Java IO: 字符流的Piped和CharArray
  8. [编程入门]宏定义之闰年判断:给年份year,定义一个宏,以判别该年份是否闰年。提示:宏名可以定义为LEAP_YEAR,形参为y,既定义宏的形式为 #define LEAP_YEAR(y) (读者设计
  9. 使用java读取文件并输出
  10. 银行营业网点管理系统——entity类(Branches)