Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

老ER里refresh 为啥只刷新控件,而不重载render整个 tpl #162

Open
Phinome opened this issue Jul 17, 2015 · 1 comment
Open

Comments

@Phinome
Copy link

Phinome commented Jul 17, 2015

R;T

首先,声明的是这个问题,提到这个Repo里可能不太合适,因为,我发现现在的ER里都没有 refresh 方法了,不过,希望各位大大指点,索性就提到这个里面了。

好了,回到正题:

之所以提出这个问题,是因为我在实际使用过程中遇到这样的问题。

问题描述:
qq20150717-2 2x

如上图所示,现在的实际情况是,第一个框里的文字是模板变量映射model的值;第二个框是引入 echarts 绘制的图表。那么问题来了,挖掘机。。。(哦,跑题了)

当季度标签切换的时候整个model将会刷新,从而引起两个地方的联动,一个是紧接季度标签下的收入标签表格以及第一个红框中的文字;另一个就是 echarts 绘制的图表。

然后,一开始我就想当然的在 Action 中使用了 me.refresh() ,写好后,我开心的按下了F5,开始切换季度标签,等待奇迹的发生,然后,等等,貌似只有表格刷新了。难道是我的使用姿势不对?不禁怀疑自己是不是用错地方了,然后回去翻了一下之前的代码,“没问题啊!之前也是这么写的!”,再然后,看了一下源代码,就知道 refresh 只刷新了控件,没有按我主观的对于 refresh 的认识那样,对整个 page 进行刷新。Ps: 这里多说一点,我的理解是:当 Model 刷新时,View 中与 Model 对应的数据也应执行相应的刷新,而不仅仅限于控件。

陷入了困境了。

解决方案:

请教了一下高人,然后得知用onentercomplete 就能搞定了。coding !F5 ,切换标签,奇迹发生了。

最后,那么还是那个问题,(不是挖掘机)为啥,this.refresh 不重新 render tpl。进一步而言就是:当我触发Action refresh 的时候,Model 刷新了,但是 tpl 中映射的变量也应该刷新。

然后,可能也是我使用的问题,或者说这种提法是有问题,因此,不知各位怎么看吧。

Review 了三遍Post,还是不太确定是否完全表述清楚我的意思,能让各位明晰。😂😂😂

@errorrik

@errorrik
Copy link

这是老ER的问题。新ER里其实也有相应的机制,只不过不在ER这个repo下了。

首先,这基于一种假设:我们认为页面不一定是需要全部变化的。比如我们进入一个列表页面,然后点击了第二页,这时列表的表头可以不用变化,只局部刷新表格的内容区域。要实现这样的场景,我们需要知道什么东西是可变化的。通常情况下,有两种做法:

  1. 自动法:当render时,抽析出模板中变量的部分。这种做法用起来比较方便,但实际上比较麻烦。首先变化的一定是页面中的DOM,但你render的时候面对的是字符串,你需要按相应的规则parse出变化的部分(对应的是什么变量,属于DOM中的什么部分,text还是attr等),才能方便的构建映射。后续更新时,对于复杂的数据结构,你可能需要做diff,这个开销是很大的。
  2. 手动法:手工标识哪些东西是可变的。这个听起来不太现实,使用太麻烦了。但老ER正是这么做的,不是全手工,但是基于了一些规则。

老ER的做法是:

  1. 视图渲染的步骤,在框架层面做了一层抽象,分成render和repaint。当页面首次进入时,进入render过程;当二次进入(hash的path部分不变,参数变化时),进入repaint过程。这个抽象便于在视图渲染中实现局部刷新。但是ER并没规定一定要做这事。
  2. 视图render的步骤是:通过模板引擎填充HTML -> 渲染UI组件(初始化组件 -> 在当前环境下保存组件的引用 -> 为组件填充数据 -> 调用组件的render方法)
  3. 在上面的步骤中,视图能够知道当前有哪些组件,每个组件使用哪些数据了。这时候后面的局部刷新就好做了。在视图repaint中,我们只对组件进行刷新,步骤如下:遍历所有组件 -> 填充数据 -> 调用组件的render方法。

从上面的几点可以看出来:

  1. 局部刷新是由UI组件完成的(一个Table组件,第二次render的时候,只刷数据区域还是刷新全部,这件事情交给Table组件来决定。一个Select,value变化时只刷新显示区域这种事情也是Select自己完成)
  2. 视图缓存也是UI组件完成的(数据不变的时候,视图是否重新刷新,这个逻辑也交给UI组件)

综上,对老ER和ESUI集成的默认方案来说,我们认为UI组件是数据显示与变化的载体。对于你上面的case,建议使用Label组件来承载需要变化的红框文字内容。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants