Last active
December 28, 2015 13:13
-
-
Save otakustay/1226822d1daa533d0e55 to your computer and use it in GitHub Desktop.
yuri demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Engine} form './Engine'; | |
import {tpl} from 'text!./tpl/dialog.tpl'; | |
let engine = new Engine('dialog'); | |
engine.compile(tpl); | |
export default class Dialog extends Control { | |
constructor(...args) { | |
super(...args); | |
// 这个方法事实上会拿出一个继承自`engine`的模板引擎实例,用于做模板的重写 | |
this.setTemplateEngine(engine); | |
} | |
/** | |
* 处理数据变化时对应的UI更新逻辑 | |
* | |
* @protected | |
* @override | |
*/ | |
initializeUIUpdate() { | |
// 基类实现任何属性变化时重绘 | |
this.enableAutoRepaint(); | |
// 有些属性变化时不需要重绘,给去掉,主要为了性能 | |
this.supressRepaintForProperty(['left', 'top', 'initialDraggingPosition']); | |
// `left`和`top`这种对主元素生效的,默认的重绘逻辑无用,得自己处理,这里用FRP来做 | |
this.uiModel.on( | |
'update', | |
({changes}) => { | |
if (changes.hasOwnProperty('top') || changes.hasOwnProperty('left')) { | |
$(this.main).css(this.uiModel.pick('left', 'top'); | |
} | |
} | |
); | |
// 如果支持FRP,也可以用FRP来写 | |
// import {hasAnyProperty} from './reactive-update'; | |
// 筛选出变化集中包含`left`或`top`属性的事件流 | |
// let moveStream = hasAnyChange('left', 'top'); | |
// 把事件流注册到`uiModel`上去,添加自理函数 | |
// moveStream.connect( | |
// this.uiModel, | |
// () => $(this.main).css(this.uiModel.pick('left', 'top')) | |
// ); | |
// 如果FRP可被接受的话,更建议用FRP来实现这一块的逻辑 | |
} | |
/** | |
* 绑定事件 | |
* | |
* @protected | |
* @override | |
* @return {Object} | |
*/ | |
bindEvents() { | |
super.bindEvents(); | |
// 可以自己写逻辑绑定事件 | |
// | |
// `query`方法会翻译选择器,其中的`#foo`会被翻译为part id,而`.foo`会被翻译为part class | |
// | |
// 所有对控件的修改都通过某个属性的变化来实现,如此处关闭对话框用的是`isVisible`属性的修改 | |
$(this.query('.header')).on( | |
'mousedown', | |
(e) => { | |
this.set('isDragging', true) | |
this.set('initialDraggingPosition', {x: e.clientX, y: e.clientY}); | |
let move = (e) => { | |
let initialPosition = this.get('initialDraggingPosition'); | |
let diff = { | |
x: e.clientX - initialPosition.x, | |
y: e.clientY - initialPosition.y | |
}; | |
// 此类临时的操作与控件的状态无关,不用修改控件的属性 | |
${this.main}.css('transform', `translate(${diff.x}, ${diff.y})`); | |
}; | |
let doc = $(document); | |
doc.on('mousemove', move); | |
doc.on( | |
'mouseup', | |
(e) => { | |
let initialPosition = this.get('initialDraggingPosition'); | |
let diff = { | |
x: e.clientX - initialPosition.x, | |
y: e.clientY - initialPosition.y | |
}; | |
$(this.main).css('transform', ''); | |
// 会影响到控件状态的就要通过修改属性来实现 | |
let command = { | |
initialDraggingPosition: ${set: null}, | |
left: {$set: this.get('left') + diff.x}, | |
top: {$set: this.get('top') + diff.y} | |
}; | |
this.update(command); | |
} | |
); | |
} | |
); | |
$(this.query('#close')).on('click', () => this.set('isVisible', false)); | |
// 简单的事件也可以直接返回一个对象,对象的key是事件名和选择器的组合,选择器对应`query`方法,value是一个函数 | |
return { | |
'click #close': () => this.set('isVisible', false); | |
}; | |
} | |
// 可以直接使用decorator关联事件 | |
// | |
// 第一个参数是一个选择器,对应`query`方法 | |
// | |
// 所有事件会绑定在主元素上,使用事件代理实现 | |
// | |
// 事件可以是一个函数,也可以是一个字符串指定某个方法名 | |
// | |
// 所有事件调用时的`this`是当前控件实例 | |
@event('.button', 'click') | |
[Symbol()](e) { | |
// `e`是DOMEvent对象 | |
this.fire('buttonclick', {tag: $(e.target).data('tag')}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- target: main --> | |
<!-- import: header --> | |
<!-- import: body --> | |
<!-- import: foot --> | |
<!-- target: header --> | |
<header id="${id.header}" class="${class.header}"> | |
<!-- import: headerContent --> | |
</header> | |
<!-- target: headerContent --> | |
<h3 id="${id.title}"> | |
<!-- import: title --> | |
</h3> | |
<!-- import: closeButton --> | |
<!-- target: title --> | |
${title} | |
<!-- target: closeButton --> | |
<i id="${id.close}" class="ui-icon ui-icon-times ${class.close}">关闭</i> | |
<!-- target: body --> | |
<div id="${id.body}" class="${class.body}"> | |
<!-- import: bodyContent --> | |
</div> | |
<!-- target: bodyContent --> | |
<!-- if: ${encodeBody} --> | |
${content} | |
<!-- else --> | |
${content|raw} | |
<!-- /if --> | |
<!-- target: foot --> | |
<!-- if: ${hasFoot} | |
<footer id="${id.foot}" class="${class.foot}"> | |
<!-- import: footContent --> | |
</footer> | |
<!-- /if --> | |
<!-- target: footContent --> | |
<!-- if: ${footContent} --> | |
<!-- if: ${encodeFoot} --> | |
${footContent} | |
<!-- else --> | |
${footContent|raw} | |
<!-- /if --> | |
<!-- elif: ${buttons} --> | |
<!-- for: ${buttons} as ${button} --> | |
<!-- use: button(button = ${button}) --> | |
<!-- /for --> | |
<!-- /if --> | |
<!-- target: button --> | |
<button type="button" class="${class.button} ${class.button}-${button.tag}" data-tag="${button.tag}">${button.text}</button> | |
<!-- 没想好怎么解决子控件问题 --> | |
<!-- <esui-button type="button" variants="${button.tag}" text="${button.text}"></esui-button> --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- {{foo}}为JavaScript表达式 --> | |
<!-- {=foo}为双向绑定 --> | |
<!-- {-foo}为单向绑定 --> | |
<!-- {foo}为一次性绑定 --> | |
<esui-dialog id="warning" is-visible="{{false}}" title="{=warnTitle}" content="{=warnMessage}"> | |
<!-- 重写掉title这个target --> | |
<script type="text/yuri-template" for="title"> | |
[警告]${title} | |
</script> | |
</eusi-dialog> | |
<script> | |
require( | |
['emc/Model', 'esui'], | |
function (Model, esui) { | |
var model = new Model(); | |
model.set('warnTitle', '你完了'); | |
model.set('warnMessage', '你真的完了'); | |
esui.render(document.body, model); | |
model.set('warnTitle', '好像得救了'); | |
} | |
); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
require( | |
['emc/Model', 'esui/Dialog'], | |
function (Model, Dialog) { | |
var model = new Model(); | |
model.set('warnTitle', '你完了'); | |
model.set('message', '你真的完了'); | |
var options = { | |
// `config`表示一次性的值,直接给出值,没有绑定功能 | |
config: { | |
hasFoot: false | |
}, | |
// 如果`autoBinding`为`true`,则默认按同名原则进行**双向**绑定,默认是`true`的 | |
autoBinding: true, | |
// `bindings`表示绑定,在`autoBinding`的基础上可以额外加一些映射,与HTML的方式相同 | |
bindings: { | |
title: '=warnTitle' | |
} | |
} | |
var dialog = new Dialog(model, options); | |
dialog.appendTo('body'); | |
// 通过操作控件属性变化其UI | |
dialog.set('title', '好像得救了'); | |
// 会获取`"好像得救了"`,因为是双向绑定 | |
console.log(model.get('warnTitle')); | |
// 同样会改变控件的UI,不推荐两种方式混用 | |
model.set('message', '快跑吧'); | |
} | |
); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment