Eng 刚刚迎来了0.9.4的最新版本 , 除了解决所有已知的bug , 最主要的新特性 就是增加了组件( 循环通信响应 ).
众所周知组件间互相watch 响应 , 如果没有加入判断条件 , 则会进入死循环状态 , 而且如果双方都必须对对方的通信做出明确响应的时候 , 双方都不得不要做好对相应数据内容的判断 , 防止僵死.
两个组件尚且如此复杂 , 如果一个特殊的组件群 ,彼此群发循环响应 , 这个判断你来怎么写 ? 是不是比初涉node 时的 回调噩梦 还要可怕? 这简直就是 watch 噩梦
下面进入正题:
PS : Eng 实行组件闭包全局无关的思想 (所有该组件的相关操作都应写在created方法内), 所以Eng 即使在完全闭包的情况下 , 也能与所有已存在和将要添加的组件通信 , 访问操纵其所有的参数方法 , 前提你必须声明这些组件id和谁有关
html
<div id='app1'>
<p>成员 : {{name}}</p>
<p>{{msg}}</p>
</div>
<div id='app2'>
<p>成员 : {{name}}</p>
<p>{{msg}}</p>
</div>
<div id='app3'>
<p>成员 : {{name}}</p>
<p>{{msg}}</p>
</div>
javascript
var app1=new Eng({
el:document.getElementById('app1'),
id:'app1',
relate:['app2','app3'], //和app1有关的组件id列表
watcher:{
msg:function( oldValue ,newValue, items ,cache){ //以下简写
var member=items.$_relate; // == [app1,app2] 已关联的组件
var l=member.length;
if(newValue=='')return;
// 这里判断newValue是否为空 , 是因为 Eng 的watch 是立即执行的
// $_watcher 才是先注册后触发
items.$_caller=true; // 主叫
while(l--){
var app= items[member[l]];
app.$_gData.msg=items.$_id+' : '+newValue;
}
},
data:{
name:'app1',
msg:'',
},
created:function(items , cache){
//items.$_watcher({xxx:fun(){}}) 如果不想立即触发watcher
}
});
var app2=new Eng({
el:document.getElementById('app2'),
id:'app2',
relate:['app1','app3'],
watcher:{
msg:function( o ,n, i ,c){
var m=i.$_relate;
var l=m.length;
if(n=='')return;
i.$_caller=true;
while(l--){
var a= i[m[l]];
a.$_gData.msg=i.$_id+' : '+n;
};
}
},
data:{
name:'app2',
msg:''
}
});
var app3=new Eng(
el:document.getElementById('app3'),
id:'app2',
relate:['app1','app3'],
watcher:{
msg:function( o ,n, i ,c){
var m=i.$_relate;
var l=m.length;
if(n=='')return;
i.$_caller=true;
while(l--){
var a= i[m[l]];
a.$_gData.msg=i.$_id+' : '+n;
};
}
},
data:{
name:'app2',
msg:''
}
});从上面代码中 relate 参数告知了组件我和哪些 id 的组件有关 , 即使是后添加的组件 , 也能顺利关联 ,事实上只要其中一方关联 , 对方 的items参数中就会包含对方 , items.$id_+ idname
而且通过watcher关系 我们可以看到这三个组件都是有彼此群发响应通信关系的 , 都 监控 msg 的值变化 , 也都没有互相判断 响应 成立条件 .
因为 items.$_caller = true; 主叫机制 , 从底层断开了watch 的死循环的可能 . 可以理解为:现在我是主叫 , 你们都老老实实听我说话 , 不得插嘴..
到此, 完美诠释了Eng 循环群发通信相应机制的应用实现 . 可能有些同学对此嗤之以鼻 , 但是你不妨通过 不使用Eng 的主叫机制 , 或者用其它 同类js 工具的watch 实现 群发循环通信响应试试 , 我想绝非易事.....
下面进入命令截图阶段:
原始画面:
app1.msg=' 好久不见! 十分想念! 互相问个好呗 ?'
app2.msg=' 是啊 好久不见 , 你们好';
app3.msg=' 哎! app1和app2 上次一别 , 久矣!'
感兴趣的同学 , 可以尝试 编写自己的场景多员群发通信小游戏
总结 : 加入 items.$_caller=true 的主叫声明机制 , 将事件群发的主控判断权牢牢掌握在主叫手中 , 仅需"主叫"调度控制 , 无需 "被叫" 端做任何数据判断 , 做到只管发不管收 , 成功的避免了在混乱的组件群发通信响应时大量的逻辑判断 . 尤其在循环响应时 , 更免除了逻辑渗漏会陷入 watch噩梦 的隐患.