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

打通数据驱动与事件驱动机制 #679

Open
Brunoon opened this issue Aug 14, 2019 · 6 comments
Open

打通数据驱动与事件驱动机制 #679

Brunoon opened this issue Aug 14, 2019 · 6 comments
Assignees
Labels

Comments

@Brunoon
Copy link
Contributor

Brunoon commented Aug 14, 2019

要解决什么问题

目前有:
1、数据驱动:通过 mip-data、mip-bind 能够将元素的属性和数据进行绑定,从而实现数据的变化影响元素的样式
2、事件驱动:通过 on 语法监听组件和全局抛出的事件,并触发元素的行为或者改变数据

所以现在 "事件->数据" 是可行的,但是 "数据->事件" 还没有支持,如果数据的变化能够触发特定事件或者行为,就能够完全由数据驱动,只需要修改数据就可以控制页面的样式与行为,便于开发与维护。

描述一下你理想中的解决方案

参考 amp 绑定特定属性触发行为的做法,比如 amp-lightbox,可以绑定 open 属性,控制组件的显示与隐藏状态,对应 open 和 close 行为。

该方案可以通过为组件添加 observedAttributes 和 attributeChangedCallback 实现。

描述你的备选方案

mip-data 监听数据的变化,当数据变化时抛出 data-changed 事件,从而触发相应行为。

由于数据变化不容易检测,而且对性能有较大影响,因此该方案不建议使用。

@clark-t
Copy link
Contributor

clark-t commented Aug 19, 2019

#679
目前为了解决 MIP 官方组件的 attributeChanged 实现程度较低的问题,新增了内置组件 <mip-data-watch> 来实现数据到事件的转换:

<mip-data-watch
  watch="data.key"
  on="change:element-id.doSomething(xxx)"
></mip-data-watch>

其中 watch 的取值与 MIP.watch 的第一个值相同,即仅支持点运算符的数据访问,为了支持更为复杂的表达式,我们可以选择将负责表达式的计算结果写到 data.key 里面来即可:

<div on="tap:MIP.setData({ data: { key: (a.b + c.d * 10086) } })">赋值</div>

从而扩展了 mip-data-watch 的适用范围。

@clark-t clark-t added the has PR label Aug 19, 2019
@clark-t
Copy link
Contributor

clark-t commented Aug 23, 2019

现在有个比较尴尬的点是,如果想要在一些全局方法或者是 MIP 组件方法里面获取 mip-data 数据,在目前情况下是不能直接实现的,但可以使用 <mip-data-watch> 拐个弯来获取:

<div on="tap:MIP.setData({
  url: 'https://www.baidu.com?user=' + user + '&age=' + age
})">click me</div>
<mip-data-watch 
  watch="url" 
  on="change:MIP.navigateTo(url=event.newValue)" 
  layout="nodisplay"></mip-data-watch>

这里存在两个问题:

  1. 如果 url 没有任何变化的话,就永远不会触发 onchange 事件;
  2. 无法控制当前的 url 变化后的值是不是真正需要的;

因此最好能够提供一些方法来解决这些问题

@clark-t
Copy link
Contributor

clark-t commented Aug 23, 2019

新的想法是,新增一个官方组件 <mip-action> 提供全部的表达式解析支持:

<div on="tap:ac.execute">
<mip-action
  id="ac"
  conditon="abc > 0 && cde < 0"
  execute="id.doSomething(arg1=abc + cde, arg2=efg)"
></mip-action>

@Brunoon
Copy link
Contributor Author

Brunoon commented Aug 23, 2019

目前来看 <mip-action> 能够比较好地解决这个问题,
但是由于写法上与一般的 action 不同,在页面中容易引起混乱并导致用户写错,
是否能够全部 action 都支持表达式解析?

@clark-t
Copy link
Contributor

clark-t commented Sep 9, 2019

经讨论之后认为,对于 MIP.navigateTo、MIP.scrollTo 等这些使用类似 AMP 的新版参数形式的写法下,支持受限制的运算之后,能够以最小的代价和最小的影响面来让行为读取到 mip-data 里的数据:

<mip-data>
  <script type="application/json">
  {
    "a": 1
  }
  </script>
</mip-data>
<div on="MIP.navigateTo(url='https://www.baidu.com?a=' + a)">click me</div>

同时 mip-action-macro 的功能主要是提供一个 conditon 判断条件来通过当前的状态判断是否要执行方法:

<mip-action-macro
  condition="a > 1"
  on="execute:MIP.navigateTo(url=host + '?a=' + a)"
></mip-action-macro>

@clark-t
Copy link
Contributor

clark-t commented Sep 24, 2019

目前 MIP on 表达式里面可以使用 MIP.navigateTo、MIP.scrollTo 等等全局对象方法,但是这些方法并没有在 mip-script 当中暴露出来,形式上就不够统一,但是把他们开放给 mip-script 又担心开发者过渡依赖 mip-script 导致网页体验变差。
所以到底需不需要暴露出去呢?

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

No branches or pull requests

2 participants