【4858美高梅】不吻合复杂的前端项目,HTML也足以静态编写翻译

By admin in 4858美高梅 on 2019年2月28日

虚拟 DOM 已死?

2016/10/24 · 基本功技术 ·
1 评论 ·
DOM

本文小编: 伯乐在线 –
ThoughtWorks
。未经小编许可,禁止转载!
迎接参加伯乐在线 专辑小编。

本体系小说:

  • 《缘何 ReactJS
    不符合复杂的前端项目?》
  • 《React.Component
    损害了复用性?》

本连串的上一篇文章《React.Component
损害了复用性?》探究了如何在前端开发中编辑可复用的界面成分。本篇文章将从性质和算法的角度比较Binding.scala 和其余框架的渲染机制。

Binding.scala 完结了一套精确数据绑定机制,通过在模板中央银行使 bind
for/yield 来渲染页面。你恐怕用过局地别样 Web
框架,大多采取脏检查可能虚拟 DOM 机制。和它们比较,Binding.scala
的纯粹数据绑定机制使用更简约、代码更健全、品质更高。

正文小编杨博。

HTML也得以静态编写翻译?

2016/11/30 · HTML5 · 1
评论 ·
binding.scala,
React,
前端

正文小编: 伯乐在线 –
【4858美高梅】不吻合复杂的前端项目,HTML也足以静态编写翻译。ThoughtWorks
。未经小编许可,禁止转发!
欢迎加入伯乐在线 专栏撰稿人。

More than React体系文章:

《More than
React(一)为啥ReactJS不合乎复杂的前端项目?》

《More than
React(二)React.Component损害了复用性?》

《More than React(三)虚拟DOM已死?》

《More than
React(四)HTML也得以静态编写翻译?》


《More than
React》种类的上一篇文章《虚拟DOM已死?》正如了Binding.scala和其它框架的渲染机制。本篇作品上将介绍Binding.scala中的XHTML语法。

为何 ReactJS 不吻合复杂的前端项目?

2016/08/17 · JavaScript
· 15 评论 ·
React,
ReactJS,
前端

正文小编: 伯乐在线 –
ThoughtWorks
。未经笔者许可,禁止转发!
迎接出席伯乐在线 专辑笔者。

《More than
React》体系的篇章会一起分成五篇。本文是第②篇,介绍用ReactJS开发时遇上的各样难点。后边四篇小说的每一篇将会分别详细谈论之中一个难题,以及Binding.scala咋样消除这些题材。

ReactJS虚拟DOM的缺点

比如说, ReactJS 使用虚拟 DOM 机制,让前者开发者为各类组件提供叁个
render 函数。render 函数把 propsstate 转换到 ReactJS 的虚构
DOM,然后 ReactJS 框架依据render 重回的虚构 DOM 创建相同结构的诚实
DOM。

每当 state 更改时,ReactJS 框架重新调用 render 函数,获取新的虚拟
DOM 。然后,框架会相比较上次生成的杜撰 DOM 和新的虚构 DOM
有哪些差距,进而把差距应用到真实 DOM 上。

这么做有两大毛病:

  1. 每次 state 更改,render 函数都要生成完全的虚拟 DOM,哪怕 state
    改动相当的小,render函数也会全体总计3回。要是 render
    函数很复杂,那一个历程就会白白浪费很多测算能源。
  2. ReactJS 框架相比虚拟 DOM
    差距的进程,既慢又易于出错。比如,你想要在某些 <ul>
    列表的顶部插入一项 <li> ,那么 ReactJS 框架会误以为你改改了 <ul>
    的每一项 <li>,然后在底部插入了2个 <li>

那是因为 ReactJS 收到的新旧四个虚拟 DOM 之间交互独立,ReactJS
并不知道数据源产生了何等操作,只好依照新旧三个虚拟 DOM
猜测内需实践的操作。自动的推测算法既不准又慢,必必要前端开发者手动提供
key 属性、shouldComponentUpdate 方法、componentDidUpdate 方法或许
componentWillUpdate 等办法才能扶助 ReactJS 框架猜对。

前端 binding.scala data-binding scala.js web

其它前端框架的标题

背景介绍

二零一八年 4 月,笔者第2回在有些客户的项目中接触到ReactJS 。

本人发觉ReactJS要比作者从前用过的AngularJS不难很多,它提供了响应式的多寡绑定作用,把数据映射到网页上,使本人可以轻松达成互动不难的网站。

不过,随着小编越来越深远的行使ReactJS,笔者发觉用ReactJS编写交互复杂的网页很狼狈。
笔者盼望有一种方法,能够像ReactJS一样简单化解简单难题。除此以外,还要能简单消除复杂难点。

于是乎笔者把ReactJS用Scala重新写了多个。代码量从近10000行降到了一千多行。

用这么些框架达成的TodoMVC应用,只用了154行代码。而用ReactJS实现均等效果的TodoMVC,需要488行代码。

下图是用Binding.scala实现的TodoMVC应用。

4858美高梅 1

其一框架就是Binding.scala。

AngularJS的脏检查

除了类似 ReactJS 的虚构 DOM 机制,其余流行的框架,比如 AngularJS
还会利用脏检查算法来渲染页面。

看似 AngularJS 的脏检查算法和 ReactJS
有一样的欠缺,不可能获悉景况修改的企图,必须完全重新总括 View
模板。除此之外,AngularJS 更新 DOM
的范围往往会比实际所需大得多,所以会比 ReactJS 还要慢。

本连串的上一篇小说组件对复用性有害?研究了何等在前端开发中编辑可复用的界面成分。本篇小说中校从质量和算法的角度相比较Binding.scala 和其他框架的渲染机制。

对HTML的残缺帮助

从前大家使用其它前端框架,比如Cycle.js
、Widok、ScalaTags时,由于框架不接济HTML语法,前端工程师被迫浪费大批量时光,手动把HTML改写成代码,然后稳步调节和测试。

纵然是支撑HTML语法的框架,比如ReactJS,帮衬境况也很七零八落。

比如说,在ReactJS中,你无法这么写:

JavaScript

class BrokenReactComponent extends React.Component { render() { return (
<ol> <li class=”unsupported-class”>不支持 class
属性</li> <li style=”background-color: red”>不支持 style
属性</li> <li> <input type=”checkbox”
id=”unsupported-for”/> <label for=”unsupported-for”>不支持 for
属性</label> </li> </ol> ); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class BrokenReactComponent extends React.Component {
  render() {
    return (
      <ol>
        <li class="unsupported-class">不支持 class 属性</li>
        <li style="background-color: red">不支持 style 属性</li>
        <li>
          <input type="checkbox" id="unsupported-for"/>
          <label for="unsupported-for">不支持 for 属性</label>
        </li>
      </ol>
    );
  }
}

前端工程师必须手动把 classfor 属性替换到 className
htmlFor,还要把内联的 style
样式从CSS语法改成JSON语法,代码才能运转:

JavaScript

class WorkaroundReactComponent extends React.Component { render() {
return ( <ol> <li className=”workaround-class”>被迫把 class
改成 className</li> <li style={{ backgroundColor: “red”
}}>被迫把体制表改成 JSON</li> <li> <input
type=”checkbox” id=”workaround-for”/> <label
htmlFor=”workaround-for”>被迫把 for 改成 htmlFor</label>
</li> </ol> ); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class WorkaroundReactComponent extends React.Component {
  render() {
    return (
      <ol>
        <li className="workaround-class">被迫把 class 改成 className</li>
        <li style={{ backgroundColor: "red" }}>被迫把样式表改成 JSON</li>
        <li>
          <input type="checkbox" id="workaround-for"/>
          <label htmlFor="workaround-for">被迫把 for 改成 htmlFor</label>
        </li>
      </ol>
    );
  }
}

那种开发格局下,前端工程师即使能够把HTML原型复制粘贴到代码中,但还供给多量改造才能实际运营。比Cycle.js、Widok或然ScalaTags省相连太多事。

题材一:ReactJS组件难以在复杂交互页面中复用

ReactJS中的最小复用单位是组件。ReactJS的机件比AngularJS的Controller和View
要轻量些。 每种组件只要求前端开发者提供多少个 render 函数,把 props
state 映射成网页成分。

那般的轻量级组件在渲染不难静态页面时很好用,
可是若是页面有互动,就无法不在组件间传递回调函数来处总管件。

本人将在《More than React(二)组件对复用性有毒?》中用原生DHTML
API、ReactJS和Binding.scala达成同贰个急需复用的页面,介绍Binding.scala怎么着简单完结、简单复用复杂的相互逻辑。

Binding.scala的精确数据绑定

Binding.scala 使用精确数据绑定算法来渲染 DOM 。

在 Binding.scala 中,你能够用 @dom 注脚证明数据绑定表明式。@dom
会自动把 = 之后的代码包装成 Binding 类型。

比如:

@dom val i: Binding[Int] = 1 @dom def f: Binding[Int] = 100 @dom val
s: Binding[String] = “content”

1
2
3
@dom val i: Binding[Int] = 1
@dom def f: Binding[Int] = 100
@dom val s: Binding[String] = "content"

@dom 既可用以 val 也能够用来 def ,能够发挥包罗 IntString
在内的其余数据类型。

而外,@dom 方法还足以平昔编写 XHTML,比如:

@dom val comment: Binding[Comment] = <!– This is a HTML Comment
–> @dom val br: Binding[HTMLBRElement] = <br/> @dom val seq:
Binding[BindingSeq[HTMLBRElement]] = <br/><br/>

1
2
3
@dom val comment: Binding[Comment] = <!– This is a HTML Comment –>
@dom val br: Binding[HTMLBRElement] = <br/>
@dom val seq: Binding[BindingSeq[HTMLBRElement]] = <br/><br/>

这些 XHTML 生成的
Comment

HTMLBRElement
是 HTML
Node
的派生类。而不是
XMLNode。

每个 @dom 方法都能够依靠其余数据绑定表明式:

val i: Var[Int] = Var(0) @dom val j: Binding[Int] = 2 @dom val k:
Binding[Int] = i.bind * j.bind @dom val div:
Binding[HTMLDivElement] = <div>{ k.bind.toString }</div>

1
2
3
4
val i: Var[Int] = Var(0)
@dom val j: Binding[Int] = 2
@dom val k: Binding[Int] = i.bind * j.bind
@dom val div: Binding[HTMLDivElement] = <div>{ k.bind.toString }</div>

由此这种情势,你能够编写 XHTML 模板把数量源映射为 XHTML
页面。那种精确的照耀关系,描述了数额里面包车型大巴涉嫌,而不是 ReactJS 的
render
函数那样描述运算进程。所以当数码爆发改变时,唯有受影响的有些代码才会另行计算,而不需求再度计算整个
@dom 方法。

比如:

val count = Var(0) @dom def status: Binding[String] = { val startTime
= new Date “本页面开头化的时辰是” + startTime.toString + “。按钮被按过”

  • count.bind.toString + “次。按钮最后2次按下的时光是” + (new
    Date).toString } @dom def render = { <div> { status.bind }
    <button onclick={ event: 伊芙nt => count := count.get + 1
    }>更新情状</button> </div> }
1
2
3
4
5
6
7
8
9
10
11
12
13
val count = Var(0)
 
@dom def status: Binding[String] = {
  val startTime = new Date
  "本页面初始化的时间是" + startTime.toString + "。按钮被按过" + count.bind.toString + "次。按钮最后一次按下的时间是" + (new Date).toString
}
 
@dom def render = {
  <div>
    { status.bind }
    <button onclick={ event: Event => count := count.get + 1 }>更新状态</button>
  </div>
}

如上代码能够在ScalaFiddle实际上运作一下试行。

注意,status
并不是二个普通的函数,而是描述变量之间关系的特别表明式,每一遍渲染时只实行个中一些代码。比如,当
count 改变时,只有位于 count.bind 今后的代码才会再次总括。由于
val startTime = new Date 位于 count.bind
在此之前,并不会重复计算,所以会直接维持为开拓网页第一遍举办时的初叶值。

稍加人在念书 ReactJS 恐怕 AngularJS 时,需求学习 key
shouldComponentUpdate$apply$digest 等繁杂概念。那些概念在
Binding.scala 中一直不存在。因为 Binding.scala 的 @dom
方法描述的是变量之间的关联。所以,Binding.scala
框架知道确切数据绑定关系,能够自动物检疫查和测试出须要更新的微小部分。

Binding.scala 达成了一套精确数据绑定机制,通过在模板中应用 bind
for/yield 来渲染页面。你或者用过一些其余 Web
框架,大多使用脏检查或许虚拟 DOM 机制。和它们比较,Binding.scala
的规范数据绑定机制使用更简短、代码更结实、品质更高。

不般配原生DOM操作

其余,ReactJS等部分前端框架,会生成虚拟DOM。虚拟DOM不能够合作浏览器原生的DOM
API
,导致和jQuery、D3等其他库同盟时困难重重。比如ReactJS更新DOM对象时经常会破坏掉jQuery控件。

Reddit重重人议论了这么些题材。他们从未主意,只可以弃用jQuery。作者司的某客户在用了ReactJS后也被迫用ReactJS重写了大批量jQeury控件。

题材二:ReactJS的虚构DOM 算法又慢又不准

ReactJS的页面渲染算法是虚构DOM差量算法。

开发者供给提供 render 函数,根据 propsstate 生成虚拟 DOM。
然后 ReactJS 框架遵照 render 重返的虚拟 DOM 创设相同结构的诚实 DOM.

每当 state 更改时,ReacJS 框架重新调用 render 函数,获取新的虚拟 DOM
。 然后,框架会相比较上次生成的杜撰 DOM 和新的虚构 DOM
有何不同,然后把差别应用到实际DOM上。

诸如此类做有两大缺陷:

  1. 每次 state 更改,render 函数都要生成完全的虚构 DOM. 哪怕 state
    改动十分的小,render函数也会完好总括三回。借使 render
    函数很复杂,那么些进程就白白浪费了过多盘算能源。
  2. ReactJS框架相比虚拟DOM差距的长河,既慢又便于出错。比如,要是你想要在有个别
    <ul>列表的顶部插入一项 <li> ,那么ReactJS框架会误以为你改改了
    <ul> 的每一项 <li>,然后在底部插入了3个 <li>

那是因为
ReactJS收到的新旧多少个虚拟DOM之间交互独立,ReactJS并不知道数据源产生了哪些操作,只可以依照新旧八个虚拟DOM来猜测急需执行的操作。
自动的估计算法既不准又慢,必须求前端开发者手动提供 key
属性、shouldComponentUpdate 方法、componentDidUpdate 方法依然
componentWillUpdate 等措施展才能能帮助 ReactJS 框架猜对。

自笔者将在《More than
React(三)虚拟DOM已死?》中相比较ReactJS、AngularJS和Binding.scala渲染机制,介绍简单品质高的Binding.scala精确数据绑定机制。

结论

本文相比了虚拟 DOM 、脏检查和纯粹数据绑定两种渲染机制。

AngularJS ReactJS Binding.scala
渲染机制 脏检查 虚拟DOM 精确数据绑定
数据变更时的运算步骤
  1. 重复检查数据是否更改
  2. 大范围更新页面,哪怕这部分页面根本没有修改
  1. 重新生成整个虚拟DOM
  2. 比较新旧虚拟DOM的差异
  3. 根据差异更新页面
  1. 直接根据数据映射关系,更新最小范围页面
检测页面更新范围的准确性 不准 默认情况下不准,需要人工提供keyshouldComponentUpdate才能准一点
需要前端工程师理解多少API和概念才能正确更新页面 很多 很多 只有@dombind两个概念
总体性能 非常差

这三种机制中,Binding.scala
的确切数据绑定机制概念更少,效用更强,质量更高。作者将在下一篇小说中介绍
Binding.scala 如何在渲染 HTML 时静态检查语法错误和语义错误,从而幸免 bug

1 赞 收藏 1
评论

ReactJS 虚拟 DOM 的缺点

诸如, ReactJS 使用虚拟 DOM 机制,让前者开发者为各样组件提供三个
render 函数。render 函数把 propsstate 转换来 ReactJS 的虚拟
DOM,然后 ReactJS 框架依照 render 重返的虚构 DOM 成立相同结构的真人真事
DOM.

每当 state 更改时,ReacJS 框架重新调用 render 函数,获取新的虚构 DOM
。然后,框架会相比上次生成的杜撰 DOM 和新的杜撰 DOM
有啥样差异,然后把差别应用到实在 DOM 上。

如此那般做有两狂胜笔:

  1. 每次 state 更改,render 函数都要生成完全的虚拟 DOM. 哪怕 state
    改动十分小,render函数也会整中华全国体育总会结三次。假诺 render
    函数很复杂,那么些进度就白白浪费了成都百货上千乘除财富。
  2. ReactJS 框架相比较虚拟 DOM
    差其余进度,既慢又不难失误。比如,借使你想要在某些 <ul>
    列表的顶部插入一项 <li> ,那么 ReactJS 框架会误以为你改改了 <ul>
    的每一项 <li>,然后在尾部插入了四个 <li>

那是因为 ReactJS 收到的新旧多少个虚拟 DOM 之间相互独立,ReactJS
并不知道数据源产生了什么操作,只好依照新旧五个虚拟 DOM
猜测亟需执行的操作。自动的臆度算法既不准又慢,必供给前端开发者手动提供
key 属性、shouldComponentUpdate 方法、componentDidUpdate 方法大概
componentWillUpdate 等方法才能支持 ReactJS 框架猜对。

Binding.scala中的XHTML

今后有了Binding.scala ,能够在@dom办法中,直接编写XHTML。比如:

JavaScript

@dom def introductionDiv = { <div style=”font-size:0.8em”>
<h3>Binding.scala的优点</h3> <ul>
<li>简单</li> <li>概念少<br/>功能多</li>
</ul> </div> }

1
2
3
4
5
6
7
8
9
@dom def introductionDiv = {
  <div style="font-size:0.8em">
    <h3>Binding.scala的优点</h3>
    <ul>
      <li>简单</li>
      <li>概念少<br/>功能多</li>
    </ul>
  </div>
}

如上代码会被编写翻译,直接开立真实的DOM对象,而从未虚构DOM。

Binding.scala对浏览器原生DOM的支撑很好,你能够在那些DOM对象上调用DOM
API,与 D叁 、jQuery等其它库交互也统统没有失水准。

ReactJS对XHTML语法的欠缺不全。比较之下,Binding.scala扶助完整的XHTML语法,前端工程师能够一直把设计好的HTML原型复制粘贴到代码中,整个网站就能够运作了。

标题三:ReactJS的HTML模板效能既不完备、也不硬朗

ReactJS支持用JSX编写HTML模板。

辩论上,前端工程师只要把静态HTML原型复制到JSX源文件中,
增添部分变量替换代码, 就能改造成动态页面。
理论上那种做法要比Cycle.js、Widok、ScalaTags等框架更契合复用设计师提供的HTML原型。

不幸的是,ReactJS对HTML的支撑一鳞半爪。开发者必须手动把classfor属性替换到classNamehtmlFor,还要把内联的style体制从CSS语法改成JSON语法,代码才能运作。
那种开发形式下,前端工程师纵然能够把HTML原型复制粘贴到代码中,但还必要多量改造才能实际运营。
比Cycle.js、Widok、大概、ScalaTags省不断太多事。

除外,ReactJS还提供了propTypes体制校验虚拟DOM的合法性。
可是,这第②建工公司制也漏洞百出。
固然钦赐了propTypes,ReactJS也不可能在编写翻译前提前发现错误。只有测试覆盖率很高的档次时才能在种种组件使用其余零件时实行校验。
即便测试覆盖率很高,propTypes依旧无法检测出拼错的属性名,假如您把onClick写成了onclick
ReactJS就不会报错,往往造成开发者额外开支大量小时排查二个很简单的bug。

自作者将在《More than
React(四)HTML也得以编写翻译?》中相比较ReactJS和Binding.scala的HTML模板,介绍Binding.scala怎么着在全部援救XHTML语法的还要静态检查语法错误和语义错误。

关于小编:ThoughtWorks

4858美高梅 2

ThoughtWorks是一家中外IT咨询公司,追求杰出软件品质,致力于科技(science and technology)驱动商业变革。擅长构建定制化软件出品,支持客户高效将概念转化为价值。同时为客户提供用户体验设计、技术战略咨询、组织转型等咨询服务。

个人主页 ·
作者的稿子 ·
84 ·
  

4858美高梅 3

AngularJS 的脏检查

除了类似 ReactJS 的虚构 DOM 机制,其余流行的框架,比如 AngularJS
还会接纳脏检查算法来渲染页面。

看似 AngularJS 的脏检查算法和 ReactJS
有同等的缺陷,不可能获知处境修改的企图,必须完整重新计算 View
模板。除此之外,AngularJS 更新 DOM
的限定往往会比其实所需大得多,所以会比 ReactJS 还要慢。

Binding.scala中XHTML的类型

@dom主意中XHTML对象的品种是Node的派生类。

比如,<div></div>
的类别就是HTMLDivElement,而
<button></button> 的连串正是
HTMLButtonElement。

此外, @dom
申明会修改总体艺术的重临值,包装成1个Binding。

JavaScript

@dom def typedButton: Binding[HTMLButtonElement] = {
<button>按钮</button> }

1
2
3
@dom def typedButton: Binding[HTMLButtonElement] = {
  <button>按钮</button>
}

注意typedButton是个原生的HTMLButtonElement,所以能够直接对它调用 DOM
API。比如:

JavaScript

@dom val autoPrintln: Binding[Unit] = {
println(typedButton.bind.innerHTML) // 在控制德雷斯顿打字与印刷按钮内部的 HTML }
autoPrintln.watch()

1
2
3
4
@dom val autoPrintln: Binding[Unit] = {
  println(typedButton.bind.innerHTML) // 在控制台中打印按钮内部的 HTML
}
autoPrintln.watch()

那段代码中,typedButton.bind.innerHTML 调用了 DOM API
HTMLButtonElement.innerHTML。通过autoPrintln.watch(),每当按钮爆发更新,autoPrintln中的代码就会实行三遍。

难点四:ReactJS与服务器通讯时索要复杂的异步编程

ReactJS从服务器加载数据时的架构能够看成MVVM(Model–View–ViewModel)情势。
前端工程师必要编写制定多少个数据库访问层作为Model,把ReactJS的state当做ViewModel,而render用作View。
Model负责访问数据库并把数量设置到state(即View
Model)上,可以用Promise和fetch API实现。
然后,render,即View,负责把View Model渲染到页面上。

在那整个流程中,前端程序员必要编写制定大批量闭包组成的异步流程,
设置、访问状态的代码五零四散,
一非常的大心就会bug丛生,即便如履薄冰的处理各类异步事件,也会促成程序变得复杂,既难调节和测试,又难保障。

本人将在《More than
React(五)为何别用异步编制程序?》中相比ReactJS和Binding.scala的数额同步模型,介绍Binding.scala怎样自动同步服务器数据,幸免手动异步编制程序。

Binding.scala 的可信赖数据绑定

Binding.scala 使用精确数据绑定算法来渲染 DOM 。

在 Binding.scala 中,你能够用 @dom 阐明注脚数据绑定表明式。@dom
会自动把 = 之后的代码包装成 Binding 类型。

比如:

@dom val i: Binding[Int] = 1
@dom def f: Binding[Int] = 100
@dom val s: Binding[String] = "content"

@dom 既可用于 val 也得以用来 def ,可以表明包罗 IntString
在内的其余数据类型。

除外,@dom 方法还足以一向编写 XHTML,比如:

@dom val comment: Binding[Comment] = <!-- This is a HTML Comment -->
@dom val br: Binding[HTMLBRElement] = <br/>
@dom val seq: Binding[BindingSeq[HTMLBRElement]] = <br/><br/>

这些 XHTML 生成的
Comment

HTMLBRElement
是 HTML
Node
的派生类。而不是 XML
Node。

每个 @dom 方法都得以借助其他数据绑定表明式:

val i: Var[Int] = Var(0)
@dom val j: Binding[Int] = 2
@dom val k: Binding[Int] = i.bind * j.bind
@dom val div: Binding[HTMLDivElement] = <div>{ k.bind.toString }</div>

经过那种办法,你能够编写 XHTML 模板把数量源映射为 XHTML
页面。那种精确的映照关系,描述了多少里面包车型大巴涉及,而不是 ReactJS 的
render
函数那样描述运算进度。所以当数码产生变更时,唯有受影响的有的代码才会再也总括,而不要求再行计算整个
@dom 方法。

比如:

val count = Var(0)
@dom def status: Binding[String] = {
  val startTime = new Date
  "本页面初始化的时间是" + startTime.toString + "。按钮被按过" + count.bind.toString + "次。按钮最后一次按下的时间是" + (new Date).toString
}
@dom def render = {
  <div>
    { status.bind }
    <button onclick={ event: Event => count := count.get + 1 }>更新状态</button>
  </div>
}

4858美高梅,如上代码能够在ScalaFiddle事实上运作一下蓄势待发。

注意,status
并不是一个常备的函数,而是描述变量之间关系的特有表明式,每一次渲染时只实行在那之中一些代码。比如,当
count 改变时,唯有位于 count.bind 以往的代码才会再度总结。由于
val startTime = new Date 位于 count.bind
之前,并不会再也总计,所以会一贯维系为打开网页第叁遍实施时的初步值。

稍微人在读书 ReactJS 或然 AngularJS 时,供给上学 key
shouldComponentUpdate$apply$digest 等繁杂概念。那几个概念在
Binding.scala 中一贯不存在。因为 Binding.scala 的 @dom
方法描述的是变量之间的涉及。所以,Binding.scala
框架知道确切数据绑定关系,可以自动检查和测试出须要更新的小不点儿部分。

其他HTML节点

Binding.scala支持HTML注释:

JavaScript

@dom def comment = { <!– 你看不见作者 –> }

1
2
3
@dom def comment = {
  <!– 你看不见我 –>
}

Binding.scala也支持CDATA块:

JavaScript

@dom def inlineStyle = { <section> <style><![CDATA[
.highlight { background-color:gold } ]]></style> <p
class=”highlight”>Binding.scala真好用!</p> </section> }

1
2
3
4
5
6
7
8
9
10
@dom def inlineStyle = {
  <section>
    <style><![CDATA[
      .highlight {
        background-color:gold
      }
    ]]></style>
    <p class="highlight">Binding.scala真好用!</p>
  </section>
}

结论

尽管Binding.scala初看上去很像ReactJS,
但隐藏在Binding.scala背后的体制更不难、更通用,与ReactJS和Widok截然不一样。

故而,通过简化概念,Binding.scala灵活性更强,能用通用的法门缓解ReactJS解决不了的复杂难点。

譬如说,除了上述五个地方以外,ReactJS的情况管理也是疑难难点,借使引入Redux恐怕react-router那样的第③方库来拍卖情状,会促成架构变复杂,分层变多,代码绕来绕去。而Binding.scala能够用和页面渲染一样的数据绑定机制描述复杂的事态,不须求其余第2方库,就能提供服务器通讯、状态管理和网址分发的效应。

以下表格中列出了上述Binding.scala和ReactJS的效能差别:

Binding.scala

ReactJS

复用性

小小复用单位

方法

组件

复用难度

随便交互内容依然静态内容都简单复用

不难复用静态内容组件,但难以启齿复用交互组件

页面渲染算法

算法

确切的多寡绑定

虚拟 DOM

性能

正确性

电动保障科学

亟需开发者手动设置 key 属性,不然复杂的页面会混杂。

HTML 模板

语法

Scala XML 字面量

JSX

是否协理 HTML 或 XHTML 语法

全体协理 XHTML

残缺协助。不奇怪的 XHTML 不或者编写翻译。开发者必须手动把 classfor
属性替换到 classNamehtmlFor,还要把内联的 style 样式从 CSS
语法改成 JSON 语法。

何以校验模板语法

机动编译时校验

运行时经过 propTypes 校验但不能检查和测试大约的拼写错误。

服务器通信

机制

电动远程数据绑定

MVVM + 异步编程

落到实处难度

简单

复杂

其他

什么分摊网址恐怕锚点链接

帮助把网址当成普通的绑定变量来用,无需第2方库。

不扶助,需求第③方库 react-router

意义完备性

完全的前端开发化解方案

自笔者只含有视图部分作用。要求格外领悟 react-router 、 Redux
等第2方库才能兑现完全的前端项目。

上学曲线

API 简单,对没用过 Scala 的人来说也很好懂

上心灵。但效能太弱导致前期学习第叁方库时曲线陡峭。

Binding.scala

ReactJS

三个多月前,作者在Scala.js的论坛发布Binding.scala时,当时Scala.js社区最流行的响应式前端编程框架是Widok。TimNieradzik是Widok的作者。他在见到本身公布的框架后,表彰这么些框架是Scala.js社区最有前途的
HTML 5渲染框架。

她是对的,多个月后,未来Binding.scala已经变成Scala.js社区最风靡的响应式前端编制程序框架。

Awesome
Scala网站比较之下了Scala的响应式前端编制程序框架,Binding.scala的活跃程度和流行度都比Udash、Widok等别的框架要高。

4858美高梅 4

自身在如今的多少个品类中,也稳步丢弃JavaScript和ReactJS,改用Scala.js和Binding.scala搭建新时期的前端技术栈。

结论

正文比较了虚拟 DOM 、脏检查和准确数据绑定两种渲染机制。

那两种体制中,Binding.scala
的纯正数据绑定机制概念更少,功效更强,品质更高。作者将在下一篇文章中牵线
Binding.scala 如何在渲染 HTML 时静态检查语法错误和语义错误,从而制止 bug

内嵌Scala代码

除却能够把XHTML内嵌在Scala代码中的 @dom 方法中,Binding.scala 还协理用
{ ... } 语法把 Scala 代码内嵌到XHTML中。比如:

JavaScript

@dom def randomParagraph = { <p>生成3个专断数: {
math.random.toString }</p> }

1
2
3
@dom def randomParagraph = {
  <p>生成一个随机数: { math.random.toString }</p>
}

XHTML中内嵌的Scala代码能够用 .bind 绑定变量只怕调用其余 @dom
方法,比如:

JavaScript

val now = Var(new Date) window.setInterval(一千) { now := new Date }
@dom def render = { <div> 未来时间:{ now.bind.toString } {
introductionDiv.bind } { inlineStyle.bind } { typedButton.bind } {
comment.bind } { randomParagraph.bind } </div> }

1
2
3
4
5
6
7
8
9
10
11
12
13
val now = Var(new Date)
window.setInterval(1000) { now := new Date }
 
@dom def render = {
  <div>
    现在时间:{ now.bind.toString }
    { introductionDiv.bind }
    { inlineStyle.bind }
    { typedButton.bind }
    { comment.bind }
    { randomParagraph.bind }
  </div>
}

上述代码渲染出的网页中,时间会动态改变。

有关链接

  • Binding.scala
    项目主页
  • Binding.scala • TodoMVC
    项目主页
  • Binding.scala • TodoMVC
    DEMO
  • Binding.scala • TodoMVC 以外的别样
    DEMO
  • JavaScript 到 Scala.js
    移植指南
  • Scala.js 项目主页
  • Scala API
    参考文书档案
  • Scala.js API
    参考文书档案
  • Scala.js DOM API
    参考文书档案
  • Binding.scala急迅上手指南
  • Binding.scala
    API参考文书档案
  • Binding.scala 的 Gitter
    聊天室

    1 赞 5 收藏 15
    评论

强类型的 XHTML

Binding.scala中的XHTML 都扶助静态类型检查。比如:

JavaScript

@dom def typo = { val myDiv = <div
typoProperty=”xx”>content</div> myDiv.typoMethod() myDiv }

1
2
3
4
5
@dom def typo = {
  val myDiv = <div typoProperty="xx">content</div>
  myDiv.typoMethod()
  myDiv
}

由于上述代码有拼写错误,编写翻译器就会报错:

JavaScript

typo.scala:23: value typoProperty is not a member of
org.scalajs.dom.html.Div val myDiv = <div
typoProperty=”xx”>content</div> ^ typo.scala:24: value
typoMethod is not a member of org.scalajs.dom.html.Div
myDiv.typoMethod() ^

1
2
3
4
5
6
typo.scala:23: value typoProperty is not a member of org.scalajs.dom.html.Div
        val myDiv = <div typoProperty="xx">content</div>
                     ^
typo.scala:24: value typoMethod is not a member of org.scalajs.dom.html.Div
        myDiv.typoMethod()
              ^

有关作者:ThoughtWorks

4858美高梅 5

ThoughtWorks是一家中外IT咨询公司,追求杰出软件品质,致力于科学和技术驱动商业变革。擅长创设定制化软件出品,扶助客户高效将概念转化为价值。同时为客户提供用户体验设计、技术战略咨询、组织转型等咨询服务。

个人主页 ·
笔者的篇章 ·
84 ·
  

4858美高梅 6

内联CSS属性

style 属性设置内联样式时,style 的值是个字符串。比如:

JavaScript

@dom def invalidInlineStyle = { <div style=”color: blue;
typoStyleName: typoStyleValue”></div> }

1
2
3
@dom def invalidInlineStyle = {
  <div style="color: blue; typoStyleName: typoStyleValue"></div>
}

如上代码中设置的 typoStyleName 样式名写错了,但编写翻译器并不曾报错。

要想让编写翻译器能检查内联样式,能够用 style: 前缀而不用 style
属性。比如:

JavaScript

@dom def invalidInlineStyle = { <div style:color=”blue”
style:typoStyleName=”typoStyleValue”></div> }

1
2
3
@dom def invalidInlineStyle = {
  <div style:color="blue" style:typoStyleName="typoStyleValue"></div>
}

那么编写翻译器就会报错:

JavaScript

typo.scala:28: value typoStyleName is not a member of
org.scalajs.dom.raw.CSSStyleDeclaration <div style:color=”blue”
style:typoStyleName=”typoStyleValue”></div> ^

1
2
3
typo.scala:28: value typoStyleName is not a member of org.scalajs.dom.raw.CSSStyleDeclaration
        <div style:color="blue" style:typoStyleName="typoStyleValue"></div>
         ^

这样一来,能够在编制代码时就了然属性有没有写对。不像原生JavaScript /
HTML / CSS那样,蒙受bug也查不出来。

自定义属性

一旦你需求绕开对品质的品种检查,以便为HTML成分添加定制数据,你能够属性加上
data: 前缀,比如:

JavaScript

@dom def myCustomDiv = { <div
data:customAttributeName=”attributeValue”></div> }

1
2
3
@dom def myCustomDiv = {
  <div data:customAttributeName="attributeValue"></div>
}

那样一来Scala编写翻译器就不会报错了。

结论

本文的欧洲经济共同体DEMO请访问
ScalaFiddle。

从这几个示例可以看到,Binding.scala 一方面辅助完全的XHTML
,能够从高保真HTML
原型无缝移植到动态网页中,开发进度颇为顺畅。另一方面,Binding.scala
能够在编译时静态检查XHTML中冒出语法错误和语义错误,从而幸免bug 。

以下表格相比较了ReactJS和Binding.scala对HTML语法的支撑程度:

ReactJS Binding.scala
是否支持HTML语法? 残缺支持
是否支持标准的style属性? 不支持,必须改用 JSON 语法
是否支持标准的class属性? 不支持,必须改用className
是否支持标准的for属性? 不支持,必须改用htmlFor
是否支持HTML注释? 不支持
是否兼容原生DOM操作? 不兼容
是否兼容jQuery? 不兼容
能否在编译时检查出错误? 不能

本人将在下一篇小说中牵线 Binding.scala
怎么样贯彻服务器发送请求并在页面展现结果的流水生产线。

有关链接

  • Binding.scala
    项目主页
  • Binding.scala • TodoMVC
    项目主页
  • Binding.scala • TodoMVC
    DEMO
  • Binding.scala • TodoMVC 以外的其他DEMO
  • JavaScript 到 Scala.js
    移植指南
  • Scala.js 项目主页
  • Scala API
    参考文档
  • Scala.js API
    参考文书档案
  • Scala.js DOM API
    参考文档
  • Binding.scala飞速上手指南
  • Binding.scala
    API参考文书档案
  • Binding.scala 的 Gitter
    聊天室

    1 赞 1 收藏 1
    评论

关于小编:ThoughtWorks

4858美高梅 7

ThoughtWorks是一家中外IT咨询公司,追求杰出软件品质,致力于科学和技术驱动商业变革。擅长创设定制化软件出品,帮忙客户急速将定义转化为价值。同时为客户提供用户体验设计、技术战略咨询、协会转型等咨询服务。

个人主页 ·
小编的稿子 ·
84 ·
  

4858美高梅 8

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有