当前位置: 首页 > 文档资料 > Tabris 中文文档 >

EcmaScript 6,TypeScript 和 JSX

优质
小牛编辑
132浏览
2023-12-01

EcmaScript 6

Tabris.js 2支持所有ES5和大多数ES6 / ES7(又名ES2015 / ES2016)特性,并且无需像Babel这样的编译器。包括:

不支持的是(不使用编译器时):

  • async/await: 使用 then 替代。
  • import/export: 使用 require 方法和 exports 对象替代。

TypeScript

Tabris.js 2针对TypeScript 2进行了优化。TypeScript是一个类型安全的JavaScript/EcmaScript超集,并且还支持ES6模块语法 (importexport 语句) 和 async/await。可以在typescriptlang.org上找到有关TypeScript的完整指南。对于IDE,我们推荐支持tslint扩展名的Visual Studio Code,但也有很多其它合适的TypeScript IDE

在执行之前,必须将“TypeScript”文件“编译”为JavaScript。当使用tabris init命令生成新的Tabris.js应用程序时,已经包含了编译器,因此不需要额外的安装步骤。在给定的选项中,只需选择TypeScript App即可。应用生成后,执行npm start,以JavaScript的形式向你的Tabris开发者app提供TypeScript代码。在Visual Studio Code中,你也可以使用预先配置的启动任务。

只要任务仍在运行,你的TypeScript代码(src中的任何.ts文件)的更改将自动由TypeScript编译器检测。不需要重新启动。

注意类型安全

在TypeScript中,并不是所有的API,甚至不是所有的Tabris.js API都是完全类型安全的。 因此建议遵循以下一般准则:

转换:避免显式转换,因为它可以静默失败。使用type guards替代。

隐式的“any”类型:在TypeScript中any类型的值本质上和JavaScript值相同。编译器将接受对该值的任何操作,包括将其分配给确定类型的变量。如果你不给变量、字段或参数指定类型,并且不能通过赋值来推断,则可能会出现隐式的any类型。 始终给出函数参数的类型。字段和变量只有在声明时赋了值才是安全的。

控件属性访问:不要使用widget.set(key, value)widget.get(key)。而是直接像这样访问属性:widget.key = value。你还可以安全地使用属性对象:比如widget.set({key: value})new Widget({key: value})

控件事件处理:不要使用widget.on(event, handler)。而是使用widget.on({event: handler})

控件apply方法:仅使用widget.apply设置基础Widget类的属性,比如layoutData

选择器API 和 WidgetCollection:默认情况下,控件的findchildrensibling方法返回一个“混合的”WidgetCollection。这意味着你必须执行类型检查和转换以安全地从集合中获取控件,你也可以使用控件类(构造函数)作为选择器,这会使TypeScript“得到”的集合只包含该类型的实例。在这种情况下,不需要转换。例如: widget.children(Button).first('.myButton')返回一个button控件(或者 null),而不会是其他内容。应该注意的是,这种WidgetCollection的set方法仍然不是类型感知的。你可以使用forEach方法来安全地为集合中的所有控件设置属性。

NPM模块:tabris模块是自动类型安全的,但不是所有可以通过npm安装的模块都是如此。你可能需要为每个安装的npm模块手动安装声明文件

接口

在TypeScript中使用tabris模块导出tabris API使用的接口。它们是:

  • 属性/参数类型:ImageColorFontLayoutDataBoundsTransformationmargindimensionoffsetBoxDimensionsImageDataSelectorAnimationOptions
  • 通用事件对象:EventObject<T>,其中T是目标事件属性的类型。用于没有特定类型属性的事件。也是所有其他事件接口的基础。
  • change事件对象:PropertyChangedEvent<T, U>,事件属性和Uvalue属性的类型。用于所有与命名方案{propertyName}Changed匹配的事件,比如BackgroundChanged
  • 特殊事件对象:所有其他事件使用遵循命名方案{TargetType}{EventName}Event的特定接口,比如PickerSelectEvent。你可能想要使用这些来定义不使用参数解构的监听器。
  • 属性映射:这些是set方法和控件构造函数使用的接口。你可能希望在扩展控件类时使用它们来定义自己的属性映射。它们遵循命名方案{TargetType}Properties,比如CompositeProperties
  • 监听器映射:这些是onoff方法使用的接口。你可能希望在扩展控件类时使用它们来定义自己的监听器映射。它们遵循命名方案{TargetType}Events比如CompositeEvents

JSX

JSX是JavaScript / TypeScript语法的扩展,可以将代码与类似XML的声明进行混合。Tabris 2支持使用类型安全的JSX,在任何基于TypeScript的项目中开箱即用。你需要做的只是命名你的文件为.tsx而不是.ts。然后,你就可以使用JSX表达式创建控件了。例如

ui.contentView.append(
  <composite left={0} top={0} right={0} bottom={0}>
    <button centerX={0} top={100} text='Show Message' onSelect={handleButtonSelect}/>
    <textView centerX={0} top='prev() 50' font='24px'/>
  </composite>
);

与如下代码效果相同

ui.contentView.append(
  new Composite({left: 0, top: 0, right: 0, bottom: 0}).append(
    new Button({centerX: 0, top: 100, text: 'Show Message'}).on({select: handleButtonSelect}),
    new TextView({centerX: 0, top: 'prev() 50', font: '24px'})
  )
);

Tabris.js TypeScript app中的JSX遵循如下具体规则:

  • 每个JSX元素都是构造函数调用。如果直接嵌入代码中,则需要彼此分隔(见下文)。
  • 名称以小写字母开始的元素是内置元素。包括内置在Tabris.js中的所有可实例化控件,以及WidgetCollection。这些元素的类型不需要显式导入。
  • 名称以大写字母开始的元素是用户自定义元素,即扩展Tabris.js控件的任何类。这些元素需要导入。
  • 属性可以是字符串(使用单引号或双引号)或JavaScript / TypeScript表达式(使用花括号)。
  • 与控件属性名称相同的标签属性,用来通过构造函数设置该控件的属性。
  • 遵循on{EventType}命名方案的的属性用于向该事件注册监听器。
  • 每个元素可以有任何数量的子元素(如果该类型支持子元素),所有子元素都以给定的顺序添加到其父元素。
  • 要支持对用户定义的元素进行属性检查,需要在自定义控件上添加名为jsxProperties的字段。该类型必须与第一个构造函数参数的类型相匹配。你不必为该字段赋任何值。
  • 虽然JSX表达式本身是类型安全的,但是它们的返回类型不是(是any类型),因此请按照上面的转换说明进行操作。一般认为在widget.append()中使用未经检查的JSX表达式是安全的,因为所有JSX元素都是可append类型。

注意,这是合法的:

ui.contentView.append(
  <button centerX={0} top={100} text='Show Message'/>
  <textView centerX={0} top='prev() 50' font='24px'/>
);

直接嵌套在代码中的JSX元素必须像表达式一样分隔,比如下面这种情况用逗号分隔:

ui.contentView.append(
  <button centerX={0} top={100} text='Show Message'/>,
  <textView centerX={0} top='prev() 50' font='24px'/>
);

为了避免这种情况,你可以将控件包裹在WidgetCollection中。这个例子与上面的例子效果相同:

ui.contentView.append(
  <widgetCollection>
    <button centerX={0} top={100} text='Show Message'/>
    <textView centerX={0} top='prev() 50' font='24px'/>
  </widgetCollection>
);

在TypeScript之外使用JSX

如果要在不编写TypeScript的情况下使用JSX,仍然可以使用TypeScript编译器将.jsx文件转换为.js。简单创建一个TypeScript app,并在tsconfig.jsoncompilerOptions对象中添加一个条目"allowJs": true。然后将include对象中的文件名从.ts.tsx 修改为 .js.jsx。如果你使用any类型,你可能还需要调整你的校验设置。