zpin-templates
Advanced tools
Comparing version 0.0.13 to 0.0.15
@@ -56,2 +56,4 @@ 'use strict'; | ||
//指令扩展 | ||
var dataBindAttr = "rt-bind"; | ||
/** | ||
@@ -181,3 +183,8 @@ * @param {Options} options | ||
} | ||
//数据绑定 | ||
if (node.attribs[dataBindAttr]) { | ||
var value = node.attribs[dataBindAttr]; | ||
node.attribs["value"] = "{" + value + "}"; | ||
node.attribs["onChange"] = "{function(e){" + value + "=e.target.value;this.setState(this.state)}.bind(this)}"; | ||
} | ||
var props = {}; | ||
@@ -336,2 +343,3 @@ _.forOwn(node.attribs, function (val, key) { | ||
function convertHtmlToReact(node, context) { | ||
if (node.type === 'tag' || node.type === 'style') { | ||
@@ -371,2 +379,7 @@ var _ret = function () { | ||
if (node.attribs[repeatAttr]) { | ||
//为循环加上key | ||
if (node.name != "rt-virtual" && !node.attribs["key"]) { | ||
node.attribs["key"] = "{Math.random()}"; | ||
} | ||
var arr = node.attribs[repeatAttr].split(' in '); | ||
@@ -373,0 +386,0 @@ if (arr.length !== 2) { |
{ | ||
"name": "zpin-templates", | ||
"version": "0.0.13", | ||
"version": "0.0.15", | ||
"description": "Light weight templates for react -> write html get valid react code", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
730
README.md
@@ -1,160 +0,33 @@ | ||
[![NPM version][npm-image]][npm-url] | ||
[![build status][travis-image]][travis-url] | ||
[![Coverage Status][coveralls-image]][coveralls-url] | ||
### 基本语法 | ||
# React Templates | ||
* 任何有效的HTML(包括注释)都是模板(不要把注释直接写在模板里) | ||
* {}里可以写js代码 | ||
Lightweight templates for [React](http://facebook.github.io/react/index.html). | ||
* No runtime libraries. No magic. Simply precompile your way to clear React code. | ||
* Easy syntax that's similar to HTML, supported by most IDEs. | ||
* Clear separation of presentation and logic - almost zero HTML in component files. | ||
* Declarative coding ensures that the HTML that you write and the HTML you inspect look nearly identical. | ||
* Supports AMD, CommonJS, ES6, Typescript and globals. | ||
### 内置指令: | ||
## How does it work | ||
React Templates compiles an *.rt file (react template file - an extended HTML format) into a JavaScript file. | ||
This file, which uses AMD syntax, returns a function. When invoked, this function returns a virtual React DOM based on React.DOM elements and custom user components. | ||
<p>A common use case would be that a regular React component would require a JavaScript file generated from a template, | ||
and then perform `func.apply(this)`, causing the template to have that component as its context. | ||
#### rt-if | ||
这允许您向HTML的子树添加条件。 如果条件求值为true,则返回子树; 否则,不会计算。 它被实现为三元表达式。 | ||
例子: | ||
## Playground | ||
http://wix.github.io/react-templates/ | ||
## Yeoman generator | ||
https://github.com/wix/generator-react-templates | ||
## Hello react-templates | ||
Here's a sample Hello project:<br/> | ||
https://github.com/wix/hello-react-templates | ||
Here's a sample Hello project with webpack, es6 and hot reload:<br/> | ||
https://github.com/wix/react-templates-transform-boilerplate | ||
## IntelliJ / WebStorm plugin | ||
http://plugins.jetbrains.com/plugin/7648 | ||
## Basic concepts for React templates | ||
* Any valid HTML (including comments) is a template | ||
* {} to identify JS expression | ||
* Built-in directives: | ||
* [rt-if](#rt-if) | ||
* [rt-repeat](#rt-repeat) | ||
* [rt-scope](#rt-scope) | ||
* [rt-props](#rt-props) | ||
* [rt-class](#rt-class) | ||
* [rt-import](#rt-import) | ||
* ~~rt-require~~ (deprecated, use rt-import) | ||
* [rt-template](#rt-template) | ||
* [rt-include](#rt-include) | ||
* [rt-pre](#rt-pre) | ||
* [styles](#styles) | ||
* [event handlers](#event-handlers) | ||
## Why not use JSX? | ||
Some love JSX, some don't. We don't. More specifically, it seems to us that JSX is only a good fit for components with very little HTML inside. | ||
And this can be accomplished by creating DOM elements in code. Also, we like to separate code and HTML because it just feels right. | ||
## Installation | ||
You can install react-templates using npm: | ||
```shell | ||
npm install react-templates -g | ||
``` | ||
## Usage | ||
```shell | ||
rt [file.rt|dir]* [options] | ||
``` | ||
See more on CLI usage [here](https://github.com/wix/react-templates/blob/gh-pages/docs/cli.md). | ||
In most cases, this package will be wrapped in a build task, so CLI will not be used explicitly: | ||
* Grunt: [grunt-react-templates](https://github.com/wix/grunt-react-templates) | ||
* Gulp: [gulp-react-templates](https://github.com/wix/gulp-react-templates) | ||
* Broccoli: [broccoli-react-templates](https://github.com/kraftwer1/broccoli-react-templates) | ||
* Browserify plugin: [react-templatify](https://www.npmjs.com/package/react-templatify) | ||
* Webpack loader : [react-templates-loader](https://github.com/AlexanderPavlenko/react-templates-loader) | ||
### Use React Templates for Native Apps? | ||
You can get all the react templates functionality and more. [Click here for more info](https://github.com/wix/react-templates/blob/gh-pages/docs/native.md) | ||
# Template directives and syntax | ||
## Any valid HTML is a template | ||
Any HTML that you write is a valid template, except for inline event handlers ("on" attributes). See the "event handlers" section below for more information. | ||
## {} to identify JavaScript expressions | ||
To embed JavaScript expressions in both attribute values and tag content, encapsulate them in {}. | ||
If this is done inside an attribute value, the value still needs to be wrapped in quotes. For directives (see below), {} are not used. | ||
###### Sample: | ||
```html | ||
<a href="{this.state.linkRef}">{this.state.linkText}</a> | ||
``` | ||
###### Compiled: | ||
```javascript | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
return function () { | ||
return React.DOM.a({ 'href': this.state.linkRef }, this.state.linkText); | ||
}; | ||
}); | ||
<div rt-if="this.data.resultCode === 200">Success!</div> | ||
``` | ||
当resultCode等于200时会显示Success!,否则不显示 | ||
## rt-if | ||
This lets you add conditions to a subtree of HTML. If the condition evaluates to true, the subtree will be returned; otherwise, it will not be calculated. It is implemented as a ternary expression. | ||
#### rt-repeat | ||
对数组中的每个项重复一个DOM节点及其子树。 语法是rt-repeat =“itemVar,arrayExpr中的indexVar”,其中元素itemVar将在JavaScript上下文中可用,并且将创建一个itemVarIndex来表示项目的索引。 通过使用这种命名方案,重复的表达式可以访问所有级别的嵌套。 也可以使用语法rt-repeat =“itemVar,arrayExpr中的indexVar”声明自定义索引变量,在这种情况下,索引变量将是indexVar。 | ||
例子: | ||
###### Sample: | ||
```html | ||
<div rt-if="this.state.resultCode === 200">Success!</div> | ||
``` | ||
###### Compiled: | ||
```javascript | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
return function () { | ||
return this.state.resultCode === 200 ? React.DOM.div({}, 'Success!') : null; | ||
}; | ||
}); | ||
<div rt-repeat="myNum in this.data.MyNumbers">{myNumIndex}. {myNum}</div> | ||
``` | ||
MyNumbers是一个数组,这里将遍历所有的MyNumbers,myNumIndex是数组的索引,myNum是数组元素 | ||
## rt-repeat | ||
Repeats a DOM node with its subtree for each item in an array. The syntax is `rt-repeat="itemVar, indexVar in arrayExpr"`, where the element, `itemVar`, will be available in JavaScript context, | ||
and an `itemVarIndex` will be created to represent the index of the item. By using this naming scheme, repeated expressions have access to all levels of nesting. | ||
It is also possible to declare a custom index variable using the syntax `rt-repeat="itemVar, indexVar in arrayExpr"`, in which case the index variable will be `indexVar`. | ||
#### rt-virtual | ||
这个指令会创建一个虚拟节点,它并不会渲染成真实的DOM,但仍可用作指令的根,例如。 rt-if和rt-repeat。 | ||
例如 | ||
要立即重复几个节点,而不是为每个实例共享根: | ||
###### Sample: | ||
```html | ||
<div rt-repeat="myNum in this.getMyNumbers()">{myNumIndex}. {myNum}</div> | ||
``` | ||
###### Compiled: | ||
```javascript | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
function repeatMyNum1(myNum, myNumIndex) { | ||
return React.DOM.div({}, myNumIndex + '. ' + myNum); | ||
} | ||
return function () { | ||
return _.map(this.getMyNumbers(), repeatMyNum1.bind(this)); | ||
}; | ||
}); | ||
``` | ||
## rt-virtual | ||
This directive creates as a virtual node, which will not be rendered to the DOM, but can still be used as a root for directives, e.g. `rt-if` and `rt-repeat`. | ||
###### Sample: | ||
For instance, to repeat several nodes at once without a shared root for each instance: | ||
```html | ||
<ul> | ||
@@ -164,38 +37,11 @@ <rt-virtual rt-repeat="n in [1,2,3]"> | ||
<li>{n*2}</li> | ||
</virtual> | ||
</rt-virtual> | ||
</ul> | ||
``` | ||
这里每次循环都会给出两个li标签 | ||
#### rt-scope | ||
此指令通过创建一个新方法并使用当前上下文调用它来创建一个新的JavaScript作用域。 语法是rt-scope =“expr1 as var1; expr2 as var2。这允许一个方便的速记,使代码更可读,它还有助于每个范围只执行一次表达式。 | ||
例子 | ||
##### Compiled: | ||
```javascript | ||
define([ | ||
'react/addons', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
function repeatN1(n, nIndex) { | ||
return [ | ||
React.createElement('li', {}, n), | ||
React.createElement('li', {}, n * 2) | ||
]; | ||
} | ||
return function () { | ||
return React.createElement.apply(this, [ | ||
'ul', | ||
{}, | ||
_.map([ | ||
1, | ||
2, | ||
3 | ||
], repeatN1.bind(this)) | ||
]); | ||
}; | ||
}); | ||
``` | ||
## rt-scope | ||
This directive creates a new JavaScript scope by creating a new method and invoking it with its current context. The syntax is `rt-scope="expr1 as var1; expr2 as var2`. | ||
This allows for a convenient shorthand to make the code more readable. It also helps to execute an expression only once per scope. | ||
###### Sample: | ||
```html | ||
<div rt-repeat="rpt in array"> | ||
@@ -206,82 +52,31 @@ <div rt-scope="')' as separator; rpt.val as val">{rptIndex}{separator} {val}</div> | ||
``` | ||
###### Compiled: | ||
这里调用把')'看做separator,rpt.val看做val,rt-scope这个作用域里,调用val就是调用rpt.val | ||
后续表达式可以引用前面的变量,因为生成的代码将每个别名声明为var(与函数参数相反,函数参数仅在求值之后才绑定到形式参数名称),因此可以执行类似于 | ||
```javascript | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
function scopeSeparatorVal1(rpt, rptIndex, separator, val) { | ||
return React.DOM.div({}, rptIndex + separator + ' ' + val); | ||
} | ||
function repeatRpt2(rpt, rptIndex) { | ||
return React.DOM.div({}, scopeSeparatorVal1.apply(this, [ | ||
rpt, | ||
rptIndex, | ||
')', | ||
rpt.val | ||
]), React.DOM.div({}, '\'rpt\' exists here, but not \'separator\' and \'val\'')); | ||
} | ||
return function () { | ||
return _.map(array, repeatRpt2.bind(this)); | ||
}; | ||
}); | ||
``` | ||
Subsequent expressions may reference preceding variables, since generated code declares each alias as a `var` (as opposed to a function parameter, which get bound to formal parameter names only after evaluation), | ||
so you can do stuff like | ||
```html | ||
<div rt-scope="users[userId] as user; user.profile as profile; profile.avatar as avatar;"> | ||
``` | ||
当与rt-if一起使用时,rt-if条件首先被求值,并且仅当它是真实的,才处理rt-scope映射。 这意味着你可以这样写 | ||
When used with `rt-if`, the `rt-if` condition is evaluated first, and only if it is truthy, the `rt-scope` mappings are processed. This means you can write things like | ||
```html | ||
```javascript | ||
<div rt-if="user.profile" rt-scope="user.profile.image as image"> | ||
``` | ||
这避免了去使用一个未定义的字段,否则你就要这样写user.profile && user.profile.image as image,这种写法是相当丑陋的 | ||
当与rt-repeat一起使用时,会为每次迭代计算rt-scope,以便iterations项和itemIndex在作用域中。 | ||
#### rt-props | ||
rt-props用于以编程方式将属性注入元素。 它将合并属性与模板中接收的属性。 此选项允许您基于外部逻辑构建属性并将它们传递到模板。 在将组件上设置的属性传递给模板中的元素时,它也很有用。 此属性的期望值是返回对象的表达式。 键将是属性名,值将是属性值。 | ||
例如: | ||
without risking accessing a field on an `undefined`, or doing something ugly like `user.profile && user.profile.image as image`. | ||
When used with `rt-repeat`, the `rt-scope` is evaluated for every iteration, so that iteration's `item` and `itemIndex` are in scope. | ||
## rt-props | ||
rt-props is used to inject properties into an element programmatically. It will merge the properties with the properties received in the template. | ||
This option allows you to build properties based on external logic and pass them to the template. It is also useful when passing properties set on the component to an element within the template. | ||
The expected value of this attribute is an expression returning an object. The keys will be the property name, and the values will be the property values. | ||
###### Sample: | ||
```html | ||
```javascript | ||
<input style="height:10px;width:3px;" rt-props="{style:{width:'5px'},type:'text'}"/> | ||
``` | ||
###### Compiled: | ||
这里style属性将会做merge,最终得出的结果是height:10px;width:5px; | ||
而input的类型将是text | ||
#### rt-class | ||
要在编程设置类名时减少样板代码,可以使用rt-class伪指令。 它期望一个JSON对象,其中键作为类名称,布尔值作为值。 如果值为true,将包括类名称。 | ||
请注意以下事项: | ||
1.如果在同一个HTML元素上同时使用class和rt-class,它们将被合并。 | ||
例子: | ||
```javascript | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
return function () { | ||
return React.DOM.input(_.merge({}, { | ||
'style': { | ||
height: '10px', | ||
width: '3px' | ||
} | ||
}, { | ||
style: { width: '5px' }, | ||
type: 'text' | ||
})); | ||
}; | ||
}); | ||
``` | ||
## rt-class | ||
To reduce the boilerplate code when setting class names programatically, you can use the rt-class directive. It expects a JSON object with keys as class names, and a Boolean as the value. | ||
If the value is true, the class name will be included. | ||
<p>Note the following:<br/> | ||
1. In React templates, you can use the "class" attribute as you would in HTML. <br/> | ||
2. If you use both class and rt-class on the same HTML element, they get merged. | ||
###### Sample: | ||
```html | ||
<div rt-scope="{blue: true, selected: this.isSelected()} as classes"> | ||
@@ -294,33 +89,9 @@ These are logically equivalent | ||
``` | ||
###### Compiled: | ||
#### rt-include | ||
(可选)选择从rt文件中提取静态内容。 | ||
rt-include是一个“宏”,它接受一个文本文件(例如svg / html / xml)并将其注入文件,就像它是原始标记的一部分。 | ||
例子: | ||
主模板 | ||
```javascript | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
function scopeClasses1(classes) { | ||
return React.DOM.div({}, 'These are logically equivalent', React.DOM.div({ 'className': React.addons.classSet(classes) }, 'Reference'), React.DOM.div({ | ||
'className': React.addons.classSet({ | ||
blue: true, | ||
selected: this.isSelected() | ||
}) | ||
}, 'Inline'), React.DOM.div({ 'className': 'blue' + this.isSelected() ? ' selected' : '' }, 'Using the class attribute')); | ||
} | ||
return function () { | ||
return scopeClasses1.apply(this, [{ | ||
blue: true, | ||
selected: this.isSelected() | ||
}]); | ||
}; | ||
}); | ||
``` | ||
## rt-include | ||
Optionally choose to extract static contents out of rt files.<br> | ||
rt-include is a "macro" that takes a text file (e.g svg/html/xml) and injects it into the file as if it was part of the original markup. | ||
###### Sample: | ||
given `main.rt`: | ||
```html | ||
<div> | ||
@@ -330,5 +101,5 @@ <rt-include src="./my-icon.svg" /> | ||
``` | ||
my-icon.svg模板 | ||
and `my-icon.svg`: | ||
```html | ||
```javascript | ||
<svg xmlns="http://www.w3.org/2000/svg"> | ||
@@ -338,5 +109,5 @@ <rect height="50" width="50" style="fill: #00f"/> | ||
``` | ||
等效于: | ||
is equivalent to: | ||
```html | ||
```javascript | ||
<div> | ||
@@ -348,331 +119,102 @@ <svg xmlns="http://www.w3.org/2000/svg"> | ||
``` | ||
#### 事件绑定 | ||
事件处理程序通过对浏览器原生事件跨浏览器的封装,使事件处理能够跨浏览器兼容,所以以下的事件都不是浏览器原生事件,注意区别 | ||
## rt-pre | ||
###### 剪贴板事件 | ||
* onCopy 该事件在用户拷贝元素内容时触发 | ||
* onCut 该事件在用户剪切元素内容时触发 | ||
* onPaste 该事件在用户粘贴元素内容时触发 | ||
When using the option `--normalize-html-whitespace` it allows to override the whitespace removal behaviour on a specific tag. | ||
###### 键盘事件 | ||
* onKeyDown 某个键盘按键被按下。 | ||
* onKeyPress 某个键盘按键被按下并松开。 | ||
* onKeyUp 某个键盘按键被松开。 | ||
###### Sample: | ||
given `main.rt`: | ||
```html | ||
<span rt-pre> | ||
here repeating whitespaces are preserved | ||
even if --normalize-html-whitespace is on | ||
</span> | ||
<span> | ||
here repeating whitespaces are removed | ||
if --normalize-html-whitespace is on | ||
</span> | ||
``` | ||
###### 焦点事件 | ||
* onFocus 元素获取焦点时触发 | ||
* onBlur 元素失去焦点时触发 | ||
`rt-pre` is applied automatically on `<pre>` and `<textarea>` tags: | ||
###### 表单事件 | ||
* onChange 该事件在表单元素的内容改变时触发( `<input>`,` <keygen>`, `<select>`,和` <textarea>`) | ||
* onInput 元素获取用户输入时触发 | ||
* onSubmit 表单提交时触发 | ||
###### Sample: | ||
given `main.rt`: | ||
```html | ||
<pre> | ||
here repeating whitespaces are preserved | ||
even if --normalize-html-whitespace is on | ||
</pre> | ||
``` | ||
###### 鼠标事件 | ||
* onClick 当用户点击某个对象时调用的事件句柄。 | ||
* onContextMenu 在用户点击鼠标右键打开上下文菜单时触发 | ||
* onDoubleClick 当用户双击某个对象时调用的事件句柄。 | ||
* onMouseDown 鼠标按钮被按下。 | ||
* onMouseEnter 当鼠标指针移动到元素上时触发。 | ||
* onMouseLeave 当鼠标指针移出元素时触发 | ||
* onMouseMove 鼠标被移动。 | ||
* onMouseOut 鼠标从某元素移开。 | ||
* onMouseOver 鼠标移到某元素之上。 | ||
* onMouseUp 鼠标按键被松开。 | ||
## style | ||
React templates allow the settings of styles inline in HTML, optionally returning an object from the evaluation context. By default, style names will be converted from hyphen-style to camelCase-style naming. | ||
###### 拖动事件 | ||
* onDrag 该事件在元素正在拖动时触发 | ||
* onDragEnd 该事件在用户完成元素的拖动时触发 | ||
* onDragEnter 该事件在拖动的元素进入放置目标时触发 | ||
* onDragExit | ||
* onDragLeave 该事件在拖动元素离开放置目标时触发 | ||
* onDragOver 该事件在拖动元素在放置目标上时触发 | ||
* onDragStart 该事件在用户开始拖动元素时触发 | ||
* onDrop 该事件在拖动元素放置在目标区域时触发 | ||
To embed JavaScript inside a style attribute, single curly braces are used. To embed an entire object, double curly braces are used. *Note*: When embedding objects, styles must conform to camelCase-style naming. | ||
###### 选择事件 | ||
* onSelect | ||
###### Sample: | ||
```html | ||
<div> | ||
These are really equivalent | ||
<div style="color:white; line-height:{this.state.lineHeight}px">Inline</div> | ||
<div style="{{'color': 'white', 'lineHeight': this.state.lineHeight + 'px'}}">Inline</div> | ||
</div> | ||
``` | ||
###### Compiled: | ||
```javascript | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
return function () { | ||
return React.DOM.div({}, 'These are really equivalent', React.DOM.div({ | ||
'style': { | ||
color: 'white', | ||
lineHeight: this.state.lineHeight + 'px' | ||
} | ||
}, 'Inline'), React.DOM.div({ | ||
'style': { | ||
'color': 'white', | ||
'lineHeight': this.state.lineHeight + 'px' | ||
} | ||
}, 'Inline')); | ||
}; | ||
}); | ||
``` | ||
###### 触控事件 | ||
* onTouchCancel | ||
* onTouchEnd | ||
* onTouchMove | ||
* onTouchStart | ||
## stateless components | ||
Since React v0.14, [React allows defining a component as a pure function of its props](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions). | ||
To enable creating a stateless component using react templates, add the `rt-stateless` attribute to the template's root element. | ||
Using `rt-stateless` generates a stateless functional component instead of a render function. | ||
The resulting function receives `props` and `context` parameters to be used in the template instead of `this.props`. | ||
###### UI事件 | ||
* onScroll 当文档被滚动时发生的事件。 | ||
###### Sample: | ||
```html | ||
<div rt-stateless>Hello {props.person}</div> | ||
``` | ||
###### Compiled: | ||
```html | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
return function (props, context) { | ||
return React.createElement('div', {}, 'Hello ', props.person); | ||
}; | ||
}); | ||
``` | ||
###### 滚轮事件 | ||
* onWheel 该事件在鼠标滚轮在元素上下滚动时触发 | ||
## event handlers | ||
React event handlers accept function references inside of {}, such as `onClick="{this.myClickHandler}"`. When functions are not needed, lambda notation can be used, | ||
which will create a React template that creates a function for the included code. There is no performance impact, as the function created is bound to the context instead of being recreated. | ||
<p>The lambda notation has the form: `onClick="(evt) => console.log(evt)"`. In this example, **evt** is the name of the first argument passed into the inline function. | ||
With browser events, this will most likely be the React synthetic event. However, if you expect a property that starts with **on**Something, then React templates will treat it as an event handler. | ||
If you have an event handler called **onBoxSelected** that triggers an event with row and column params, you can write `onBoxSelected="(row, col)=>this.doSomething(row,col)"`. | ||
A no-param version is supported as well: `onClick="()=>console.log('just wanted to know it clicked')"`. | ||
###### 多媒体事件 | ||
* onAbort | ||
* onCanPlay | ||
* onCanPlayThrough | ||
* onDurationChange | ||
* onEmptied | ||
* onEncrypted | ||
* onEnded | ||
* onError | ||
* onLoadedData | ||
* onLoadedMetadata | ||
* onLoadStart | ||
* onPause | ||
* onPlay | ||
* onPlaying | ||
* onProgress | ||
* onRateChange | ||
* onSeeked | ||
* onSeeking | ||
* onStalled | ||
* onSuspend | ||
* onTimeUpdate | ||
* onVolumeChange | ||
* onWaiting | ||
###### Sample: | ||
```html | ||
<div rt-repeat="item in items"> | ||
<div onClick="()=>this.itemSelected(item)" onMouseDown="{this.mouseDownHandler}"> | ||
</div> | ||
``` | ||
###### Compiled: | ||
```javascript | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
function onClick1(item, itemIndex) { | ||
this.itemSelected(item); | ||
} | ||
function repeatItem2(item, itemIndex) { | ||
return React.DOM.div({}, React.DOM.div({ | ||
'onClick': onClick1.bind(this, item, itemIndex), | ||
'onMouseDown': this.mouseDownHandler | ||
})); | ||
} | ||
return function () { | ||
return _.map(items, repeatItem2.bind(this)); | ||
}; | ||
}); | ||
``` | ||
###### 图片事件 | ||
* onLoad 一幅图像完成加载。 | ||
* onError 在加载文档或图像时发生错误 | ||
## rt-import and using other components in the template | ||
In many cases, you'd like to use either external code or other components within your template. | ||
To do so, you can use an `rt-import` tag that lets you include dependencies in a syntax similar to ES6 imports: | ||
```xml | ||
<rt-import name="*" as="depVarName" from="depName"/> | ||
###### 动画事件 | ||
* onAnimationStart 该事件在 CSS 动画开始播放时触发 | ||
* onAnimationEnd 该事件在 CSS 动画结束播放时触发 | ||
* onAnimationIteration 该事件在 CSS 动画重复播放时触发 | ||
``` | ||
Once included, **depVarName** will be in scope. | ||
You can only use rt-import tags at the beginning of your template. When including React components, they can be referred to by their tag name inside a template. | ||
For example, `<MySlider prop1="val1" onMyChange="{this.onSliderMoved}">`. Nesting is also supported: `<MyContainer><div>child</div><div>another</div></MyContainer>`. | ||
两种方式去注册事件,一个是onClick =“{this.myClickHandler}”。 当不需要函数时,可以使用lambda表示法,lambda表示法的形式为:onClick =“(evt)=> console.log(evt)”。 在此示例中,evt是传递到内联函数的第一个参数的名称。但是,如果你期望一个以onSomething开头的属性,那么模板会将其视为事件处理程序。 如果你有一个名为onBoxSelected的事件处理程序触发一个行和列参数的事件,你可以写入onBoxSelected =“(row,col)=> this.doSomething(row,col)”。 还支持无参数版本:onClick =“()=> console.log('只是想知道它点击')”。 | ||
例如: | ||
Children are accessible from **this.props.children**. | ||
###### Sample: | ||
```xml | ||
<rt-import name="member" from="module-name"/> | ||
<rt-import name="member" as="alias2" from="module-name"/> | ||
<rt-import name="*" as="alias3" from="module-name"/> | ||
<rt-import name="default" as="alias4" from="module-name"/> | ||
<div> | ||
```javascript | ||
<div rt-repeat="item in items"> | ||
<div onClick="()=>this.itemSelected(item)" onMouseDown="{this.mouseDownHandler}"> | ||
</div> | ||
``` | ||
###### Compiled (ES6 flag): | ||
```javascript | ||
import * as React from 'react/addons'; | ||
import * as _ from 'lodash'; | ||
import { member } from 'module-name'; | ||
import { member as alias2 } from 'module-name'; | ||
import * as alias3 from 'module-name'; | ||
import alias4 from 'module-name'; | ||
export default function () { | ||
return React.createElement('div', {}); | ||
} | ||
``` | ||
###### Compiled (AMD): | ||
```javascript | ||
define('div', [ | ||
'react', | ||
'lodash', | ||
'module-name', | ||
'module-name', | ||
'module-name', | ||
'module-name' | ||
], function (React, _, $2, $3, alias3, $5) { | ||
'use strict'; | ||
var member = $2.member; | ||
var alias2 = $3.member; | ||
var alias4 = $5.default; | ||
return function () { | ||
return React.createElement('div', {}); | ||
}; | ||
}); | ||
``` | ||
###### Compiled (with CommonJS flag): | ||
```javascript | ||
'use strict'; | ||
var React = require('react/addons'); | ||
var _ = require('lodash'); | ||
var member = require('module-name').member; | ||
var alias2 = require('module-name').member; | ||
var alias3 = require('module-name'); | ||
var alias4 = require('module-name').default; | ||
module.exports = function () { | ||
return React.createElement('div', {}); | ||
}; | ||
``` | ||
#### deprecated: rt-require | ||
The tag `rt-require` is deprecated and replaced with `rt-import`. | ||
Its syntax is similar to `rt-import` but does not allow default imports: | ||
```html | ||
<rt-require dependency="comps/myComp" as="MyComp"/> | ||
<rt-require dependency="utils/utils" as="utils"/> | ||
<MyComp rt-repeat="item in items"> | ||
<div>{utils.toLower(item.name)}</div> | ||
</MyComp> | ||
``` | ||
## Inline Templates | ||
Although we recommend separating the templates to a separate `.rt` file, there's an option to use a template inline as the render method (à la JSX). | ||
To do that, write your code in a `.jsrt` file, and send it to react-templates with the `modules` flag set to `jsrt`. | ||
###### Sample: | ||
```javascript | ||
define(['react','lodash'], function (React, _) { | ||
var comp = React.createClass({ | ||
render: | ||
<template> | ||
<div>hello world</div> | ||
</template> | ||
}); | ||
return comp; | ||
}); | ||
``` | ||
###### Compiled (with jsrt flag): | ||
```javascript | ||
define([ | ||
'react', | ||
'lodash' | ||
], function (React, _) { | ||
var comp = React.createClass({ | ||
render: function () { | ||
return function () { | ||
return React.createElement('div', {}, 'hello world'); | ||
}; | ||
}() | ||
}); | ||
return comp; | ||
}); | ||
``` | ||
## rt-template, and defining properties template functions | ||
In cases you'd like to use a property that accepts a function and return renderable React component. | ||
You should use a **rt-template** tag that will let you do exactly that: `<rt-template prop="propName" arguments="arg1, arg2"/>`. | ||
Templates can be used only as an immediate child of the component that it will be used in. All scope variable will be available in the template function. | ||
###### Sample: | ||
```html | ||
<MyComp data="{[1,2,3]}"> | ||
<rt-template prop="renderItem" arguments="item"> | ||
<div>{item}</div> | ||
</rt-template> | ||
</MyComp> | ||
``` | ||
###### Compiled (AMD): | ||
```javascript | ||
define([ | ||
'react/addons', | ||
'lodash' | ||
], function (React, _) { | ||
'use strict'; | ||
function renderItem1(item) { | ||
return React.createElement('div', {}, item); | ||
} | ||
return function () { | ||
return React.createElement(MyComp, { | ||
'data': [ | ||
1, | ||
2, | ||
3 | ||
], | ||
'renderItem': renderItem1.bind(this) | ||
}); | ||
}; | ||
}); | ||
``` | ||
###### Compiled (with CommonJS flag): | ||
```javascript | ||
'use strict'; | ||
var React = require('react/addons'); | ||
var _ = require('lodash'); | ||
function renderItem1(item) { | ||
return React.createElement('div', {}, item); | ||
} | ||
module.exports = function () { | ||
return React.createElement(MyComp, { | ||
'data': [ | ||
1, | ||
2, | ||
3 | ||
], | ||
'renderItem': renderItem1.bind(this) | ||
}); | ||
}; | ||
``` | ||
###### Compiled (with ES6 flag): | ||
```javascript | ||
import React from 'react/addons'; | ||
import _ from 'lodash'; | ||
function renderItem1(item) { | ||
return React.createElement('div', {}, item); | ||
} | ||
export default function () { | ||
return React.createElement(MyComp, { | ||
'data': [ | ||
1, | ||
2, | ||
3 | ||
], | ||
'renderItem': renderItem1.bind(this) | ||
}); | ||
}; | ||
``` | ||
## Contributing | ||
See the [Contributing page](CONTRIBUTING.md). | ||
## License | ||
Copyright (c) 2015 Wix. Licensed under the MIT license. | ||
[npm-image]: https://img.shields.io/npm/v/react-templates.svg?style=flat-square | ||
[npm-url]: https://npmjs.org/package/react-templates | ||
[travis-image]: https://img.shields.io/travis/wix/react-templates/gh-pages.svg?style=flat-square | ||
[travis-url]: https://travis-ci.org/wix/react-templates | ||
[coveralls-image]: https://img.shields.io/coveralls/wix/react-templates/gh-pages.svg?style=flat-square | ||
[coveralls-url]: https://coveralls.io/r/wix/react-templates?branch=gh-pages | ||
[downloads-image]: http://img.shields.io/npm/dm/react-templates.svg?style=flat-square | ||
[downloads-url]: https://npmjs.org/package/react-templates |
@@ -64,2 +64,4 @@ 'use strict'; | ||
//指令扩展 | ||
const dataBindAttr="rt-bind"; | ||
/** | ||
@@ -196,3 +198,8 @@ * @param {Options} options | ||
} | ||
//数据绑定 | ||
if(node.attribs[dataBindAttr]){ | ||
const value=node.attribs[dataBindAttr]; | ||
node.attribs["value"]="{"+value+"}"; | ||
node.attribs["onChange"]="{function(e){"+value+"=e.target.value;this.setState(this.state)}.bind(this)}" | ||
} | ||
const props = {}; | ||
@@ -353,2 +360,3 @@ _.forOwn(node.attribs, (val, key) => { | ||
function convertHtmlToReact(node, context) { | ||
if (node.type === 'tag' || node.type === 'style') { | ||
@@ -385,2 +393,7 @@ context = _.defaults({ | ||
if (node.attribs[repeatAttr]) { | ||
//为循环加上key | ||
if (node.name != "rt-virtual"&&!node.attribs["key"]) { | ||
node.attribs["key"] = "{Math.random()}"; | ||
} | ||
const arr = node.attribs[repeatAttr].split(' in '); | ||
@@ -387,0 +400,0 @@ if (arr.length !== 2) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3603
271965
215