【美高梅开户网址】HTML也能够静态编写翻译,不切合复杂的前端项目

虚拟 DOM 已死?

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

本文我: 伯乐在线 –
ThoughtWorks
。未经作者许可,禁止转发!
欢迎参与伯乐在线 专栏撰稿人。

本连串作品:

  • 《干什么 ReactJS
    不吻合复杂的前端项目?》
  • 《React.Component
    损害了复用性?》

本系列的上一篇小说《React.Component
损害了复用性?》研商了哪些在前端开发中编辑可复用的界面成分。本篇文章将从品质和算法的角度比较Binding.scala 和其余框架的渲染机制。

Binding.scala 达成了一套精确数据绑定机制,通过在模板中央银行使 bind
for/yield 来渲染页面。你只怕用过部分其余 Web
框架,大多采纳脏检查只怕虚拟 DOM 机制。和它们比较,Binding.scala
的确切数据绑定机制使用更简便、代码更强壮、质量更高。

正文笔者杨博。

HTML也得以静态编写翻译?

【美高梅开户网址】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函数也会全体总计3遍。要是 render
    函数很复杂,那个历程就会白白浪费很多计量财富。
  2. ReactJS 框架比较虚拟 DOM
    差别的长河,既慢又简单出错。比如,你想要在有些 <ul>
    列表的顶部插入一项 <li> ,那么 ReactJS 框架会误以为你改改了 <ul>
    的每一项 <li>,然后在尾部插入了1个 <li>

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

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

别的前端框架的题材

背景介绍

二〇一八年 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
要轻量些。 每种组件只需求前端开发者提供1个 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 + “次。按钮最后三遍按下的时日是” + (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>,然后在尾部插入了二个 <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 机制,让前者开发者为各样组件提供2个
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就不会报错,往往导致开发者额外开销多量时刻排查1个很简短的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中的代码就会进行三遍。

标题四:ReactJS与服务器通讯时索要复杂的异步编制程序

ReactJS从服务器加载数据时的架构能够看成MVVM(Model–View–ViewModel)方式。
前端工程师必要编写制定2个数据库访问层作为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
并不是贰个平凡的函数,而是描述变量之间关系的奇特表达式,每一趟渲染时只进行当中一些代码。比如,当
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地图