HTML也足以静态编写翻译,不相符复杂的前端项目

虚拟 DOM 已死?

2016/10/24 · 基础技术 ·
1 评论HTML也足以静态编写翻译,不相符复杂的前端项目。 ·
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,
前端

本文我: 伯乐在线 –
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函数也会完好总计三回。假诺 render
    函数很复杂,那几个进度就会白白浪费很多盘算能源。
  2. ReactJS 框架相比较虚拟 DOM
    差距的长河,既慢又简单失误。比如,你想要在有个别 <ul>
    列表的顶部插入一项 <li> ,那么 ReactJS 框架会误以为你改改了 <ul>
    的每一项 <li>,然后在尾部插入了一个 <li>

那是因为 ReactJS 收到的新旧七个虚拟 DOM 之间彼此独立,ReactJS
并不知道数据源爆发了怎么操作,只可以依据新旧三个虚拟 DOM
猜测亟待实施的操作。自动的臆度算法既不准又慢,必要求前端开发者手动提供
key 属性、shouldComponentUpdate 方法、componentDidUpdate 方法照旧
componentWillUpdate 等方法才能补助 ReactJS 框架猜对。

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

别的前端框架的难点

背景介绍

2018年 4 月,笔者首先次在有些客户的体系中接触到ReactJS 。

本人意识ReactJS要比作者从前用过的AngularJS不难很多,它提供了响应式的数量绑定功能,把多少映射到网页上,使作者能够轻松达成互相之间简单的网站。

但是,随着笔者越发深远的应用ReactJS,小编发觉用ReactJS编写交互复杂的网页很劳碌。
小编愿意有一种情势,能够像ReactJS一样简单消除简单难点。别的,还要能不难消除复杂难点。

于是自个儿把ReactJS用Scala重新写了二个。代码量从近一万行降到了一千多行。

用那一个框架完结的TodoMVC应用,只用了154行代码。而用ReactJS达成平等效果的TodoMVC,需要488行代码。

下图是用Binding.scala达成的TodoMVC应用。

亚洲必赢官网 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 “本页面早先化的小运是” + start提姆e.toString + “。按钮被按过”

  • count.bind.toString + “次。按钮最终3遍按下的时间是” + (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
从前,并不会再一次计算,所以会直接维系为打开网页第2遍实践时的开始值。

稍微人在就学 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函数也会完全总结1回。假如 render
    函数很复杂,这么些进度就白白浪费了重重乘除财富。
  2. ReactJS框架比较虚拟DOM差别的经过,既慢又简单失误。比如,假设你想要在有些
    <ul>列表的顶部插入一项 <li> ,那么ReactJS框架会误以为你改改了
    <ul> 的每一项 <li>,然后在尾部插入了三个 <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函数也会完全总括1次。如若 render
    函数很复杂,那些进度就白白浪费了重重乘除财富。
  2. ReactJS 框架比较虚拟 DOM
    差距的进度,既慢又易于出错。比如,假如你想要在有个别 <ul>
    列表的顶部插入一项 <li> ,那么 ReactJS 框架会误以为你改改了 <ul>
    的每一项 <li>,然后在底部插入了1个 <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

亚洲必赢官网 2

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

个人主页 ·
小编的小说 ·
84 ·
  

亚洲必赢官网 3

AngularJS 的脏检查

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

就像 AngularJS 的脏检查算法和 ReactJS
有一样的弱点,无法获悉情状修改的意向,必须完全重新计算 View
模板。除此之外,AngularJS 更新 DOM
的界定往往会比实际所需大得多,所以会比 ReactJS 还要慢。

Binding.scala中XHTML的类型

@dom措施中XHTML对象的品种是Node的派生类。

比如,<div></div>
的种类便是HTMLDivElement,而
<button></button> 的品类正是
HTMLButtonElement。

此外, @dom
注解会修改总体艺术的重返值,包装成三个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中的代码就会执行1回。

题材四: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>
}

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

注意,status
并不是3个通常的函数,而是描述变量之间关系的尤其表明式,每一趟渲染时只进行当中部分代码。比如,当
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可以用和页面渲染一样的数额绑定机制描述复杂的气象,不必要别的第贰方库,就能提供服务器通讯、状态管理和网址分发的功用。

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

Binding.scala

ReactJS

复用性

细微复用单位

方法

组件

复用难度

无论交互内容照旧静态内容都简单复用

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

页面渲染算法

算法

准确的多寡绑定

虚拟 DOM

性能

正确性

电动保险科学

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

HTML 模板

语法

Scala XML 字面量

JSX

是否帮助 HTML 或 XHTML 语法

完整帮衬 XHTML

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

如何校验模板语法

自动编写翻译时校验

运作时通过 propTypes 校验但不可能检查和测试大致的拼写错误。

服务器通信

机制

机动远程数据绑定

MVVM + 异步编制程序

福寿无疆难度

简单

复杂

其他

怎么着分担网址恐怕锚点链接

支撑把网址当成普通的绑定变量来用,无需第贰方库。

不援救,必要第二方库 react-router

效益完备性

完整的前端开发化解方案

本人只包涵视图部分机能。需求卓殊了解 react-router 、 Redux
等第②方库才能兑现完全的前端项目。

读书曲线

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等别的框架要高。

亚洲必赢官网 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>生成二个无限制数: {
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

亚洲必赢官网 5

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

个人主页 ·
小编的篇章 ·
84 ·
  

亚洲必赢官网 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

亚洲必赢官网 7

ThoughtWorks是一家中外IT咨询集团,追求卓越软件品质,致力于科学技术驱动商业变革。擅长营造定制化软件出品,扶助客户火速将定义转化为价值。同时为客户提供用户体验设计、技术战略咨询、组织转型等咨询服务。

个人主页 ·
我的篇章 ·
84 ·
  

亚洲必赢官网 8

网站地图xml地图