4

这篇会讲下组件内部的事件处理机制,以及组件和外界通讯的处理方式(父子通讯,兄弟通讯等)

组件内的事件处理机制

第一种,直接写在标签里,用on-eventName=“eventHandler”的方式

<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="event-element">
    <template>
        <button id="myBtn" on-click="handleClick">Alert</button>
    </template>
    <script>
        Polymer({
            is: "event-element",
            handleClick: function(e){
                alert("clicked by "+ e.currentTarget.localName);
            }
        });
    </script>
</dom-module>

第二种使用EventListener的方式

<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="event-element">
    <template>
        <button id="myBtn">Alert</button>
    </template>
    <script>
        Polymer({
            is: "event-element",
            handleClick: function(e){
                alert("clicked by "+ e.currentTarget.localName);
            },
            listeners: {
                'click': 'handleClick',
                'myBtn.click': 'handleClick'
            }
        });
    </script>
</dom-module>

大家注意,这里使用了myBtn.click这种 id+.+eventName的方式,可以对内部某个id的dom进行监听。而不写id,则监听是加在整个组件之上的。大家可以跑下上面的代码看看区别。

组件对外触发一个事件

组件分装好了最终还是要被其它组件调用,与外界通讯的,如果把属性赋值作为 输入in, 那么事件就可以称为输出out了。就拿原生的input标签进行举例。 input组件的输入就是type属性赋值,输出则是onclick事件的触发。

<input type=“xxx” onclick="xxxx">

同理,对于自定义组件也一样,对于输入来说前面几篇已经介绍了properties如何在组件外被赋值。那么事件的触发我们由如何来处理呢?
Polymer给我们提供了一个fire的api让我们来触发自定义事件,来看下面的代码

<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="event-element">
    <template>
        <button id="myBtn">Alert</button>
    </template>
    <script>
        Polymer({
            is: "event-element",
            handleClick: function(e){
                //第一个参数为eventname,第二个参数为传递的值
                this.fire('kick',{'data':'transfer data'});
            },
            listeners: {
                'myBtn.click': 'handleClick'
            }
        });
    </script>
</dom-module>

对自定义事件添加监听后就可以捕获到这个“kick”的自定义事件了。我尝试了直接在组件上使用on-kick进行监听却不行,非得使用addEventListener方式,可能是polymer不支持这种写法,期望在后续版本中加以改进。

<!DOCTYPE html>
<html>
<head>
    <script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
    <link rel="import" href="components/event-element.html">
</head>

<body>
    <event-element id="eventElement"></event-element>
</body>
<script>
    HTMLImports.whenReady(function () {
        var el = document.getElementById("eventElement");
        el.addEventListener("kick", function (e) {
            alert(e.detail.data);
        });
    });
</script>
</html>

运行结果
图片描述

消息机制

这里来聊聊组件化开发的消息机制,这个并不局限于polymer或者web应用,适用于所有的组件式开发技术。其实归纳下来就是几条准则:

父子通讯:

父->子 设置子的公共属性
子->父 子触发事件,父监听事件,父捕获到子发出的事件后再做后续处理。

兄弟通讯:

兄->父 跟父子通讯一样,先通过事件把需求提交给父
父->弟 父拿到兄的需求后,统一调度,通过设属性的方式来访问弟

爷孙通讯:

参照父子通讯,一层层向上传递事件,再一层层向下设置属性,实际开发时尽量将组建的接口都设计合理避免跨n级通讯的尴尬场面

远亲通讯:

请使用前端消息总线(如单例的消息总线类)来解决这里剪不断理还乱的case,但是这类方式不宜大面积使用,父子,和兄弟间通讯还是请使用上面的几种方式。

熊丸子
5.6k 声望293 粉丝

现在sf的文章质量堪忧~~~