php局部刷新增删改查,局部刷新与模板 · Issue #18 · thx/magix-combine · GitHub

技术实现详解

magix-combine工具主要针对magix文件做处理,通常一个完整的view由js、html、css组成。

所以插件目录下以js打头的处理js文件,以tmpl打头的处理html文件,以css打头的处理css文件

而html和css又依附于js文件存在,所以统一入口在js.js插件里

我们用以下简单的模板进行解释,主要用到的是magix-combine中的tmpl模块

在tmpl.js中可以看到具体的每一步的处理流程,接下来会说到重点步骤

当我们拿到这样的模板后,除了处理html注释,就是识别html中的js代码了,即模板命令(控制)语句

这块主要由tmpl-vars.js处理

在tmpl-vars.js中,我们要把前面的模板字符串变成合法的js语句,使用的是es6中的标签模板,即上述模板经简单处理后变成如下的字符串

`

加上反撇号(`),这一步使用正则即可完成。

变成上面的字符串后,它本身就是合法的js代码了。我们为了识别局部变量和全局变量,使用acorn这个工具进行语法分析

然后对语法树遍历Identifier和VariableDeclarator,找到变量使用和变量声明的地方,这时候要自己做一下处理。因为从外到内,从上到下遍历语法树,如果当前出现的变量未进行声明,则认为是全局变量,反之则认为局部变量

我们为了后续的其它分析,在这个tmpl-vars.js中做了入侵修改,即识别完后我们对全局变量和局部变量做了“手脚“,我们在全局变量前增加了 \u0003. 这2个字符,在使用变量的地方增加了\u0001这个字符,在变量声明的地方增加了 \u0002 这个字符。这样在其它插件中做其它分析时会比较方便。

处理后即为

`

这时候已经不是合法的js代码了,不过这已经不重要了。我们再把反撇号(`)去掉,则最终为

至此tmpl-vars的任务就完成了。

接下来为了要分析上面的模板,我们要把它变成合法的html标签,所以我们使用了另外一个模块tmpl-cmd.js。对模板命令进行移除,移除后的结果为

&0

&1

&2

我们把命令移除,同时使用特殊的占位符占位,因为我们还要把命令还原回去,所以我们还要知道每个占位符对应的模板命令。我们用一个对象来记录每个占位符对应的原始模板内容

此时用于记录占位符对应模板命令的对象如下

{

'&0':'',

'&1':'',

'&2':''

}

这个时候剩余的html就是合法的html了。

接下来把这段html交给tmpl-guid.js模块进行添加guid的操作。

进入tmpl-guid模块后,上来不管三七二十一,先给每个节点都添加一个guid,当然除了特别的节点如:没有模板命令的自闭合标签

添加完guid后变成为:

&0

&1

&2

然后再次遍历,对不符合要求的guid进行移除。

移除保留规则如下:

1.如果移除子节点后,属性和剩余的内容中不存在模板命令,则移除guid

2.如果剩余内容+属性中的模板命令,变量声明和变量使用不配对,则删除guid

3.如果剩余内容+属性中的模板命令,变量声明和使用配对,则保留guid

即上述带guid的html第一次被处理时

对外层的div移除配对的子标签后(为什么要先移除子标签?因为我们要把局部刷新做到最近的节点上),在本例中把子标签span移除

&0

&2

这时候我们把这个html片断还原模板命令语句,即把&0和&2还原回旧样子

然后对这段代码进行变量声明和变量使用分析。因为每个变量前都有特殊的前缀,所以我们可以很方便的用正则识别出来:

在当前范围内声明的变量有 i 使用的局部变量有 i,当然还有一个全局变量list,全局变量我们不用管它,因为它在整个模板中都可以访问到。

我们可以看出声明和使用的变量是配对的。即:没有出现使用的局部变量未声明的情况

那么这个div标签的guid则可以保留

然后再分析子标签,这时候进行第二次的处理

子标签为

&1

同样命令还原

同样变量识别,我们发现当前范围内使用到了局部变量i,但在当前范围内并未找到声明它的地方,则说明这段html不能被单独存在,只能做为其它标签的一部分。所以span上的guid要移除。

经tmpl-guid.js处理后,最终添加的guid如下

&0

&1

&2

在tmpl-guid.js的最后,会对存在模板命令的对象进行处理,删除其中的\u0002、\u0001占位符,最终存放模板命令的对象中存放的结果如下

{

'&0':'',

'&1':'',

'&2':''

}

这时候就进入tmpl-partial.js进行子模板分析了。

经过了tmpl-guid的打guid标识后,到tmpl-partial只需要识别带mx-guid的标签即可。

所到在tmpl-partial进行子模板拆分分析时,只需要匹配带mx-guid的标签即可,因为只有这些节点才能做为局部刷新的容器节点,识别出相应的标签和内容,再从模板命令中提取出根节点对应的数据key,即完成了整个识别内容

当然在这一步还要考虑嵌套刷新等细节,比如

当数据x,y都发生改变时,mx-guid="g1"的不需要更新,因为x的变化会让g1变到最新

当y变化时,只需要更新g1即可

细节处理

关于\u0003在tmpl-partial恢复命令的时候被替换成了$,是因为我们改造了模板引擎,去掉了with语句,这个$就是变量的根节点

关于以下代码

这段代码从div的角度看,确实变量声明和使用都是配对的,但也会被移除mx-guid,凡是不带mx-guid标识的节点都不会被局部刷新。局部刷新的首要条件是当前代码片断中要包含全局变量

再比如这段代码

这段代码只有span会被识别为局部刷新

再比如这样的情况

外层缺少包括的标签,这种情况magix-combine会自动添加一个div,详见tmpl-guid.js插件的实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值