前端view指令
使用Python来写ajax交互
view指令
前端是当今技术界最不成熟、变化最快的领域,前端开发人员往往干着吃力不讨好的苦逼活。
易度前端UI框架基于Python构建,一个语言打通前后端,并实现技术的平滑过渡。
1 DOM操作
1.1 选择组件
选择器的使用,类似jquery,但是可以直接选择组件,包括:
- tree
- tabs
可以通过ID来直接定位对象:
view.select('tree#leftnav')
也可以通过klass来定位:
view.select('form.vertical')
找到当前事件触发节点最近的:
view.closest('tree') view.closest('tabs').active_panel()
在区域内部查找:
view.closest('panel').find('tree')
1.2 标准Jquery功能
对选择之后的结果,可以做如下动作:
- .val(value)
- .empty()
- .data()
- .hide()
- .focus()
- .blur()
- .remove()
- .add_class(class_name)
- .remove_class(class_name)
- .toggle_class(class_name)
- .attr(name, value)
- .data(name, value)
- .val(value)
- .css(name, value)
- .replace(value)
- .append(value)
- .prepend(value)
- .after(value)
- .before(value)
1.3 填充内容 set_content
选择到组件之后,就可以控制组件。不同的组件有不同的控制方法。
比如对于面板panel,替换body区域内容:
view.closest('panel').set_content(ui.h1('hello'))
对于标准的layout组件:
view.select('#panel-12').set_content(ui.h1('hello'))
对树 ui.tree、标签页 ui.tabs ,也有各自的接口,具体参看组件说明文档。
1.6 创建子view new_view / merge_view
默认情况下view是全局变量,会立刻输出,但是有时候
如果需要遮罩输出,需要先输出组件内容,再输出组件脚本:
print ... # 创建一个独立的子view sub_view = view.new_view() print root.call_script('xxx.xx:xxx', context=context, view=sub_view, id='xxxx', *args, **kw) print ... # 先弹出遮罩 view.modal(printed) # 再合并子view view.merge_view(sub_view)
merge_view默认立刻输出,也可以滞后或提前输出,比如强制到最末尾输出:
view.merge_view(sub_view, position=1)
其中 position 表示输出位置:
- 0: 默认值,立刻输出
- 1:滞后到最后输出
- -1:提前到最开始输出
1.7 添加水印
例如给表单添加水印:
view.select('#mytable').add_watermark(text='test\n\n\n123')
add_watermark可选参数:
- text: 水印文本
- size: 水印大小
- font: 水印字体
- color: 水印颜色
- alpha: 水印透明度
- rotation: 水印旋转度
2 网页模板
2.3 左右侧区域
设置右侧区域的内容,可以:
view.layout.right().set_content(form)
也可以在右侧区域,补充一个内容:
view.layout.right().append(form) view.layout.right().prepend(form)
左右侧列都可以显示隐藏:
view.layout.hide_left() view.layout.show_left() view.layout.hide_right() view.layout.show_right()
2.4 侧边区域
view.layout.side().set_content(ui.button('sss'))
2.6 置顶批量选择区域
选择文件、表单的时候,会出现一个横条:
view.batch_actions.set_content(ui.button('asdfas'))
可以关闭这个横条:
view.batch_actions.close()
将某个内容,加入到批量选择条:
view.batch_actions.add(obj)
2.8 view.load加载资源
可以用于加载css/js/handlerbars模板:
# 加载软件包内的资源 view.load(['xxx.xxx:js/slimbox2.js', 'xxx.ss:slimbox2.css'])
这些静态资源文件默认会依据软件包的版本,在浏览器进行缓存。
如果发生变化,只需要设置应用的版本,便可强制浏览器使用新版本的资源文件。
在js中使用 load(['xxx.xx:aaa.js']) 的时候,如果需要也分版本缓存,需要预先通知前端各个软件包的资源版本号:
view.update_resource_version('zopen.message', 'xxx.xxxx')
也可以用于加载内置和外部的资源:
# 加载内置的css、js view.load(['slimbox2.js', 'slimbox2.css']) # 加载之后运行脚本 view.load(["https://g.alicdn.com/ilw/ding/0.9.9/scripts/dingtalk.js"], scripts=""" ... """)
3 信息提示
在软件包里面, 创建一个python脚本,ui的操作通过 view 来实现
3.1 站点消息提示
操作成功的信息提示:
view.message(message)
不影响操作正常运行,但是需要警示用户:
view.message(message, 'warning', )
导致当前操作中断的错误提示:
view.message(message, 'error', )
可以指定停留时间(停留2秒):
view.message('sssss', delay=2000)
如果希望是临时飘窗显示:
view.message(message, 'float')
4 modal窗口
遮罩方式显示一个表单:
view.modal(form, width=600)
关闭当前modal窗口:
view.close_modal()
关闭所有modal窗口:
view.close_modal(True)
替换Modal窗口的内容:
view.replace_modal(content)
找到当前的modal创建:
view.active_modal()
5 网页调用
5.1 浏览器历史
如果希望当前页面支持浏览器后退:
view.history.push_state(request, title, url='') # url可选 view.history.back() view.history.go(2)
如果当前页面,只是一个modal窗口,回退的时候,希望关闭这个窗口,可以:
view.history.push_state(request, title, url, data={"modal":True})
5.2 发起服务端局部刷新请求
主动发起服务端的请求:
view.call(context, request, 'xxxx.xxx:xxx', aaa=1, bb=2)
这里发起请求和ui组件 on('click', context, reqeust, 'xxx.xxx:xxx') 是一样的。
在服务端可以通过, request.is_from_view() 来区分是否是由view发起的局部刷新请求。
6 网页临时存储
6.1 cookie操作
写入cookie:
view.cookie.set('name', 'aaa')
增加一个失效天数:
view.cookie.set('name', 'value', expires= 7);
全站点:
view.cookie.set('name', 'value', expires=7, path='/'});
删除cookie:
view.cookie.remove('name', path='/')
6.2 localstorage操作
设置一个参数:
view.storage.set('url', 'http://everydo.com')
读取并显示参数:
url = view.storage.get('url')
这个url是一个需要在前端运行才能得到的表达式,可以用作view指令的参数:
view.message(url) view.redirect(url)
删除一个数据:
view.storage.remove('url')
7 远端view指令
可以通过消息频道,在指定用户的远端web发送前端指令。
7.1 得到远端view get_view
首先要通过用户的私有通讯频道,找到远端view:
messenger = root.get_messenger() channel = messenger.get_private_channel(request.me.id) remote_view = channel.get_view(context, request)
7.2 操作远端view
接下来,可以操作远端的view:
remote_view.message('hello') remote_view.modal(ui.button('ok'))
可以看到,所有标准的view指令都可以支持的!
8 vuejs混合开发
先用view.load(...) 加载vuejs组件:
view.load(['zopen.samples:component.js'])
view.component生成组件,可以绑定数据:
view.component('todo-item', id='test', props={'items': items})
props是一个dict,传递各个属性的值,每个值可以是 list,也可以是dict。
当属性发生变化的时候,会触发save事件:
- view.component('todo-item', id='test', props={'items': items})
- .on('save', context, reqeust, 'xxx.xxx:xxx')
也可以细化响应更具体的数据变化事件(??):
- list-append事件,数据为 {'prop_name':'items', data={}} - list-insert事件,数据为 {'prop_name':'items', data={}} - list-pop {'prop_name':'items', data={}} - list-update - dict-del {'prop_name':'items', data='key'} - dict-update {'prop_name':'items', data={key:value}}
也可以绑定事件:
view.component('button-counter')\ .on('click', context, request, 'zopen.samples:ui_component', todo='clear')
通过view.model操作数据,自动更新绑定的UI
清除或者更改数据:
view.model('todo-item#test').set('items', []) view.model('todo-item#test').set('items', [{'text':'set'}])
添加数据:
view.model('todo-item#test')['items'].append({'text': todo})
批量添加数据:
view.model('todo-item#test')['items'].extend([{'text': 'extend'}])
在指定位置添加数据:
view.model('todo-item#test')['items'].insert(0, {'text': 'insert'})
在指定位置去除数据:
# 在指定位置pop view.model('todo-item#test')['items'].pop(0) # 删除最后一个 view.model('todo-item#test')['items'].pop()
修改某个数据:
# 如果items是一个list类型 view.model('todo-item#test')['items'].set(0, {'text':'set'}) # 如果items是一个dict类型 view.model('todo-item#test')['items'].set('aaa', {'text':'set'})