文档章节

处处蚊子咬,绑定事件知多少?

阿北2017
 阿北2017
发布于 2017/05/24 14:21
字数 1408
阅读 440
收藏 4
点赞 0
评论 2

接上回,上次的更改小x经理很满意,但是提出了几点意见。

她是这样说的:

  • 系统本地留log没必要弄个类,太麻烦了,日志也不需要记录具体人,有个时间即可。
  • 管理员就一个人,不要用静态方法。

经理一定是处女座的,好吧,她的要求是对的,每个事件都是具有自己的用意,有的是一个对象,有的是系统级别,有的是一类东东,看来我要先复习一下yii的事件都能绑定什么了?

yii事件支持的绑定

前面说过yii一共能绑定四种类型的函数,分别是

  • 全局函数
  • 类的静态函数
  • 对象的方法
  • 匿名函数

支持的函数理解很简单,难在使用场景,这是我们要思考的。

针对小x经理说的第一个问题,我似乎用一个匿名函数就可以搞定了,于是我改了app\controllers\UserController.php 中对于OLog的绑定逻辑

use yii\web\User;
class UserController extends Controller {

    public function __construct(){
        //  绑定事件
        $this->on(User::EVENT_AFTER_LOGIN,function($event){
			$time = date("Y-m-d H:i:s");
			Yii::info("有人在{$time}登陆了");
		}); 
        $this->on(User::EVENT_AFTER_LOGIN,['app\models\Admin','sendMail']); 
        $this->on(User::EVENT_AFTER_LOGIN,['app\models\User','notifyFirend']); 
    }

    public function actionIndex(){
        .....
        //  login               
    }
}

而对于小x经理的第二个需求,当有人登陆后将一个邮件发给一个管理员,那么应该是Admin实例化后的一个方法,看来这次我要改造Amdin观察者类了

开始改造

// Admin app\models\Admin.php
class Admin {
    public function sendMail($event){
        echo "我给管理员发了邮件";
    }
}

我将sendMail的静态化去掉了,然后修改绑定的函数类型

use yii\web\User;
class UserController extends Controller {

    public function __construct(){
        //  绑定事件
        $this->on(User::EVENT_AFTER_LOGIN,function($event){
			$time = date("Y-m-d H:i:s");
			Yii::info("有人在{$time}登陆了");
		}); 
		
		$admin = Admin::findOne(1);	//管理员id为1
        $this->on(User::EVENT_AFTER_LOGIN,[$admin,'sendMail']); 

        $this->on(User::EVENT_AFTER_LOGIN,['app\models\User','notifyFirend']); 
    }

    public function actionIndex(){
        .....
        //  login               
    }
}

接下来我准备提交本次小x给的任务,在提交前我们做一点事情,都知道on叫做绑定,trigger叫触发,那么上面这些订阅者的事件函数,我们给它们起个名字叫做 “事件处理器”,以后会用这个名字代表它们。

我是时间分隔线⛔️⛔️⛔️⛔️⛔️⛔️

10分钟后我回到了自己的位置,小x经理对本次修改很满意,但是她给了我另一个活,原话是这样:

小北啊,看来你对事件蛮有悟性的,我再给你一个事件的任务,帮你提高啊

我的心呀~拔凉拔凉的~

这次的任务如下:

  • 晚24点到第二天6点,记录系统log,不要给客户和管理员发消息,客户要觉觉、管理员要觉觉。
  • 政府说要监听每次登陆,上面的判断对政府监听不起作用,烦死它们。
  • 对于政府的监听一直放到最前面,不受后续新增事件处理器影响,也不受将来程序员有可能勿调on代码顺序所影响。

听着很复杂,偶心中窃喜,yii已经提供了功能,我知道对于一个事件有多个事件处理器的时候,事件处理器执行的顺序和绑定顺序一致,并且yii提供了一个阻断机制,你可以对一个事件处理器执行阻断后,后面的所有事件处理器都不会再执行。

这个阻断机制就是event对象的handled,默认为假,不阻断。开始写代码

use yii\web\User;
class UserController extends Controller {

    public function __construct(){
        //  绑定事件
        $this->on(User::EVENT_AFTER_LOGIN,function($event){
			$time = date("Y-m-d H:i:s");
			Yii::info("有人在{$time}登陆了");
			if(时间在晚24点和第二天6点间){
				$event->handled = true;
			}
		}); 
		
		$admin = Admin::findOne(1);	//管理员id为1
        $this->on(User::EVENT_AFTER_LOGIN,[$admin,'sendMail']); 

        $this->on(User::EVENT_AFTER_LOGIN,['app\models\User','notifyFirend']); 
    }

    public function actionIndex(){
        .....
        //  login               
    }
}

你看到了把,就是一句简单的 $event->handled = true;就ok了。

接下来我们要添加政府订阅者,我们编写了一个叫做Gov的订阅者类,它有一个叫做notify的事件处理器,并且要让他的优先级最高。

上面我们说到了事件处理器执行的顺序和on绑定顺序一致,一种方法是将Gov的绑定放到绑定列表最前面,但是这样又不满足小x经理的第三条交代,好在yii已经有该功能了。

对于绑定函数on,存在着第四个参数,当你设置该参数为flase时,此事件处理器将进入到处理器列表最前端,开始干

use yii\web\User;
class UserController extends Controller {

    public function __construct(){
        //  绑定事件
        $this->on(User::EVENT_AFTER_LOGIN,function($event){
			$time = date("Y-m-d H:i:s");
			Yii::info("有人在{$time}登陆了");
			if(时间在晚24点和第二天6点间){
				$event->handled = true;
			}
		}); 
		
		$admin = Admin::findOne(1);	//管理员id为1
        $this->on(User::EVENT_AFTER_LOGIN,[$admin,'sendMail']); 

        $this->on(User::EVENT_AFTER_LOGIN,['app\models\User','notifyFirend']); 
		$this->on(User::EVENT_AFTER_LOGIN,['app\models\Gov','notify'],null,false); 
    }

    public function actionIndex(){
        .....
        //  login               
    }
}

这样一设置,因为它处于第一位,时间范围限制不了它,以后增加的其他事件处理器,只要我保证他们的第四个参数都不是flase,则Gov永远是第一位。

ok,阻断后续事件处理器的执行、人为影响事件处理器的执行顺序,我用这两个知识点解决了小x经理的需求。

开始 git

你以为这就完事了?还没有,下回告诉你git后的故事。

输入图片说明

© 著作权归作者所有

共有 人打赏支持
阿北2017
粉丝 61
博文 54
码字总数 68986
作品 0
洛阳
加载中

评论(2)

阿北2017
阿北2017

引用来自“1076707907”的评论

yii中,控制器构造方法要求传递参数,还有,要初始化父类。yii提供了一个方便的init方法,自己的初始化逻辑可以写这里。
是的。
1076707907
1076707907
yii中,控制器构造方法要求传递参数,还有,要初始化父类。yii提供了一个方便的init方法,自己的初始化逻辑可以写这里。
setInterval的返回值类型为什么为数值?

btn[0].onclick = function(){ var timer = null; timer = setInterval(function(){ console.log('a'); },1000) console.log(typeof timer); //返回的是一个number数据类型 } DOM事件必须用绑......

SubinY
2016/12/02
32
0
Jquery on方法绑定事件后执行多次

由于某种原因 on方法绑定可能会被执行多次 ,而执行多少次 该死的效果就显示多少次。 所以需要每次绑定事件之前,对该事件解绑 用off方法解绑

lilugirl
2016/04/28
153
0
JavaScript 从入门到放弃(一)事件委托和使用innerHTML添加元素

一、使用事件委托 一个简单的需求,比如想给ul下面的li加上点击事件,点击哪个li,就显示那个li的innerHTML。这个貌似很简单!代码如下!

tinywan1227
2017/09/30
0
0
Holo osc android app RoadMap

算是前段时间的开了个坑,一直毫无计划的填着,趁着今天,半夜被蚊子咬醒的劲,就开始定下一个RoadMap 计划吧... 为了osc android app 更容易的开发,我凭着我的理解,开始肢解osc android app 的模...

打杂程序猿
2012/12/17
0
1
Redux理解

作者:Wang Namelos 链接:http://www.zhihu.com/question/41312576/answer/90782136 来源:知乎 著作权归作者所有,转载请联系作者获得授权。 1. React有props和state: props意味着父级分发...

Ethan-GOGO
2016/08/24
17
0
关于组件绑定的事件没有响应的解决方法

以下面例子讲解 下面代码,没有添加按钮的时候,绑定keyListener事件的myframe可以正常获得键盘事件,代码如下: 但是当添加按钮btn之后, 绑定keyListener事件的myframe无法获得键盘事件,代...

iborder
2016/09/05
1
0
谈谈一些有趣的CSS题目(八)-- 纯CSS的导航栏Tab切换方案

开本系列,谈谈一些有趣的 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节。 解题不考虑兼容性,题目天马行空,想到什么说什么,...

chokcoco
2016/10/13
0
0
腾讯web前端开发工程师笔试题及答案

腾讯web前端开发工程师笔试题及答案 1、 如何实现事件委托? 首先要知道什么是事件委托。 考虑一个列表,在li的数量非常少的时候,为每一个li添加事件侦听当然不会存在太多性能方面的问题,但...

至简6
2014/07/29
0
0
javascript addLoadEvent函数说明

为了在网页加载完后,同时执行多个函数,Simon Willison写了function addLoadEvent(func): function addLoadEvent(func){ var oldOnload = window.onload; if (typeof window.onload != 'f......

lijingac
2015/02/05
0
0
美团刷单事件应拿《反不正当竞争法》修订案祭旗

11月11日,央视报道,重庆游客李先生通过美团订购了丽江一家名为风花雪月的连锁客栈。在订购的美团平台上,这家客栈房间漂亮,价格便宜,留言区一片好评。住进去后实际只是普通农家小院,网图...

朱翊
2017/11/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MyBatis入门

一、安装 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version></dependency> 二、从 XML 中构建 SqlSessionFactory String r......

一个yuanbeth
12分钟前
0
0
聊聊spring cloud的LoadBalancerAutoConfiguration

序 本文主要研究一下spring cloud的LoadBalancerAutoConfiguration RibbonAutoConfiguration spring-cloud-netflix-ribbon-2.0.0.RC2-sources.jar!/org/springframework/cloud/netflix/ribb......

go4it
15分钟前
0
0
【转】使用Lombok来优雅的编码

前言 Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO)。它通过注解实现这一目的。 正文 添加依赖 在 pom.xml 文件中添加相关依赖:...

HAVENT
17分钟前
0
0
Dubbo 源码解读 —— 可支持序列化及自定义扩展

一、概述 从源码中,我们可以看出来。目前,Dubbo 内部提供了 5 种序列化的方式,分别为 fastjson、Hessian2、Kryo、fst 及 Java原生支持的方式 。 针对不同的序列化方式,对比内容如下: 名...

Ryan-瑞恩
25分钟前
0
0
MySQL内存设置—— MySQL server has gone away

set global max_allowed_packet=268435456

一梦心草
34分钟前
0
0
推导式

列表、集合和字典推导式 列表推导式是Python最受喜爱的特性之一。它允许用户方便的从一个集合过滤元素,形成列表,在传递参数的过程中还可以修改元素。形式如下: [expr for val in collect...

火力全開
39分钟前
0
0
maven配置文件settings.xml详解

settings.xml有什么用? 如果在Eclipse中使用过Maven插件,想必会有这个经验:配置settings.xml文件的路径。 settings.xml文件是干什么的,为什么要配置它呢? 从settings.xml的文件名就可以...

浮躁的码农
44分钟前
0
0
MakeCode图形化编程语言学习笔记:micro:bit编程练习题[图]

MakeCode图形化编程语言学习笔记:micro:bit编程练习题[图]: 基础训练题: Q1:摇晃micro:bit编程板,随机出现7个小动物图标中的一个,并且前后相邻两次出现的小动物不重复。 注:七个小动物...

原创小博客
44分钟前
0
0
Redis 压力测试说明

Redis 压力测试说明 redis压力测试 2014-03-24 21:41:07| 分类: 默认分类 | 标签:redis |举报|字号 订阅 这几天对比测试mongodb、redis、pg的性能,主要是在消息队列、消息处理、用户经纬度...

舒文joven
45分钟前
0
0
拉姆达表达式 追加 条件判断 Expression>

public static class PredicateBuilder {   /// <summary>   /// 机关函数应用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混应时写在AND后的OR有效   /// </summary...

Lytf
57分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部