123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- import _ from 'lodash'
- import {invokeMethod} from "./utils"
- import {windows} from './Defaults'
- export class Scope {
- /**
- * 业务模块的唯一编号
- */
- id = _.uniqueId('scope_')
- originalVjson
- /**
- * 一个 ExtJS 能接受的配置对象
- */
- vjson
- /**
- * 原始 vjsonModel 对象
- */
- model
- /**
- * 双向绑定的模型对象
- */
- viewModel
- /**
- * 构建完成之后的 Ext控件句柄
- */
- _handle
- /**
- * 与 watch 装饰器配合使用.
- * viewModel 属性更改时触发成员方法
- */
- _watchList
- /**
- * 页面显示的时候带的参数 在设计刷新的时候使用
- */
- _vjsonOption
- _dataOption
- _addWatch(tplExpress, fn) {
- if (!this._watchList) {
- this._watchList = []
- }
- this._watchList.push({watch: tplExpress, fn})
- }
- _applyWatchList() {
- _.forEach(this._watchList, item => {
- this.viewModel.bind(item.watch, item.fn.bind(this))
- })
- }
- /**
- * 产生一个当前模块有效的唯一id
- * @param key 唯一编号
- */
- uid(key) {
- return this.id + key
- }
- /**
- * 以对话框模式打开当前模块
- * @param sender 发送者(按钮或Scope对象)
- * @param vjsonOption 界面覆盖选项(可以为空)
- * @param dataOption 数据覆盖选项(可以为空)
- */
- showDialog(sender, vjsonOption, dataOption) {
- const that = this
- const vmodel = _.defaultsDeep({
- data: {}
- }, dataOption, that.model)
- this.viewModel = new Ext.app.ViewModel(vmodel);
- this.viewModel.yvanScope = this
- this._applyWatchList()
- const config = _.defaultsDeep({
- animateTarget: sender,
- viewModel: this.viewModel,
- listeners: {
- show(sender) {
- // 记录句柄
- if (sender && !that._handle) {
- that._handle = sender
- }
- // 调用onLoad回调
- try {
- that.onLoad()
- } catch (e) {
- console.error('errorAt onLoad', e)
- }
- // 如果vjson中配置了 afterrender ,需要恢复状态
- invokeMethod(that.vjson.listeners?.show, that, arguments)
- }
- },
- }, vjsonOption, that.vjson, windows)
- if (config.height === 'unset') {
- delete config.height
- }
- if (config.width === 'unset') {
- delete config.width
- }
- const holder = sender?.lookupReferenceHolder()
- // delete config.constrain
- const win = new Ext.Window(config);
- if (holder) {
- holder.add(win)
- }
- win.show();
- }
- /**
- * 以标签模式打开当前模块
- * @param vjsonOption 界面覆盖选项(可以为空)
- * @param dataOption 数据覆盖选项(可以为空)
- */
- showPage(vjsonOption, dataOption, reload = false) {
- const that = this
- this._vjsonOption = vjsonOption;
- this._dataOption = dataOption;
- const vmodel = _.defaultsDeep({
- data: {}
- }, dataOption, that.model)
- this.viewModel = new Ext.app.ViewModel(vmodel);
- this.viewModel.yvanScope = this
- this._applyWatchList()
- const config = _.defaultsDeep({
- viewModel: this.viewModel,
- listeners: {
- added(sender) {
- // 记录句柄
- if (sender && !that._handle) {
- that._handle = sender
- }
- // 调用onLoad回调
- try {
- that.onLoad()
- } catch (e) {
- console.error('errorAt onLoad', e)
- }
- // 如果vjson中配置了 afterrender ,需要恢复状态
- invokeMethod(that.vjson.listeners?.added, that, arguments)
- }
- },
- }, vjsonOption, that.vjson)
- const tt = Ext.getCmp('TT')
- tt.addScope(this, config, reload)
- return config
- }
- /**
- * 直接渲染到元素
- * @param element 渲染目标
- * @param vjsonOption 界面覆盖选项(可以为空)
- * @param dataOption 数据覆盖选项(可以为空)
- */
- renderTo(element, vjsonOption, dataOption) {
- const that = this
- this._vjsonOption = vjsonOption;
- this._dataOption = dataOption;
- const vmodel = _.defaultsDeep({
- data: {}
- }, dataOption, that.model)
- this.viewModel = new Ext.app.ViewModel(vmodel);
- this.viewModel.yvanScope = this
- this._applyWatchList()
- const config = _.defaultsDeep({
- viewModel: this.viewModel,
- renderTo: element,
- listeners: {
- afterrender(sender) {
- // 记录句柄
- if (sender && !that._handle) {
- that._handle = sender
- }
- // 调用onLoad回调
- try {
- that.onLoad()
- } catch (e) {
- console.error('errorAt onLoad', e)
- }
- // 如果vjson中配置了 afterrender ,需要恢复状态
- invokeMethod(that.vjson.listeners?.afterrender, that, arguments)
- }
- },
- }, vjsonOption, that.vjson)
- new Ext.container.Viewport(config);
- }
- reRender() {
- this.vjson = this.buildVjson()
- this.showPage(this._vjsonOption, this._dataOption, true)
- }
- /**
- * 关闭对话框(或标签页)
- */
- close() {
- this._handle.close()
- }
- /**
- * 获取 viewModel 里包含的数据(只读)
- */
- get data() {
- return this.viewModel.getData()
- }
- /**
- * 设置 viewModel 中的数据
- * 可以是 key, value 模式
- * 也可以是 {key:value} 模式
- */
- set(path, value) {
- return this.viewModel.set(path, value)
- }
- /**
- * 寻找模块内所有的 xtype 对应的对象
- * @param xtypeKey
- */
- down(xtypeKey) {
- return this._handle.down(xtypeKey)
- }
- /**
- * 获取所有设置过 Reference 名称的组件
- */
- get refs() {
- return this._handle.getReferences()
- }
- constructor({model, vjson}) {
- const that = this
- this.model = model
- this.originalVjson = _.cloneDeep(vjson)
- this.vjson = this.buildVjson()
- }
- buildVjson() {
- const that = this
- return _.defaultsDeep({
- closable: true,
- listeners: {
- afterrender(sender) {
- // 记录句柄
- if (sender && !that._handle) {
- that._handle = sender
- }
- // 调用 onRender 回调
- that.onRender()
- // 如果vjson中配置了 afterrender ,需要恢复状态
- invokeMethod(that.originalVjson.listeners?.afterrender, that, arguments)
- },
- activate(sender) {
- // 调用 onActivate 回调
- that.onActivate()
- const vm = sender.lookupViewModel()
- if (vm) {
- window['currentScope'] = sender.lookupViewModel().yvanScope
- }
- // 如果vjson中配置了 afterrender ,需要恢复状态
- invokeMethod(that.originalVjson.listeners?.activate, that, arguments)
- },
- deactivate(sender) {
- // 调用 onActivate 回调
- that.onDeactivate()
- // 如果vjson中配置了 afterrender ,需要恢复状态
- invokeMethod(that.originalVjson.listeners?.deactivate, that, arguments)
- },
- beforedestroy(sender) {
- // 调用 onBeforeDestroy 回调
- that.onBeforeDestroy()
- // 如果vjson中配置了 afterrender ,需要恢复状态
- invokeMethod(that.originalVjson.listeners?.beforedestroy, that, arguments)
- },
- beforeclose(sender) {
- // 调用 onActivate 回调
- that.onBeforeClose()
- // 如果vjson中配置了 afterrender ,需要恢复状态
- invokeMethod(that.originalVjson.listeners?.beforeclose, that, arguments)
- },
- destroy(sender) {
- // 调用 onActivate 回调
- that.onDestroy()
- // 销毁 viewModel
- // that.viewModel.destroy()
- // 如果vjson中配置了 afterrender ,需要恢复状态
- invokeMethod(that.originalVjson.listeners?.destroy, that, arguments)
- // delete that.viewModel
- // delete that.vjson
- // delete that.originalVjson
- delete that._watchList
- delete that._handle
- },
- },
- yvanScope: this,
- referenceHolder: true,
- }, this.originalVjson)
- }
- /**
- * 模块载入完成之后的回调
- */
- onLoad() {
- }
- /**
- * 渲染完成之后的回调
- */
- onRender() {
- }
- /**
- * 被激活时的回调(可能执行多次)
- */
- onActivate() {
- }
- /**
- * 进入未激活状态之前回调的函数
- */
- onDeactivate() {
- }
- /**
- * 关闭之前的回调(只有 tab 选项卡有这个选项)
- */
- onBeforeClose() {
- }
- /**
- * 组件被卸载之前的回调
- */
- onBeforeDestroy() {
- }
- /**
- * 组件卸载之后的回调
- */
- onDestroy() {
- }
- }
- /**
- * 观察装饰器,viewModel 属性更改时触发成员方法
- * @param tplExpress tpl表达式,例如 "{form.f1}"
- */
- export function watch(tplExpress, deep = false) {
- return function (target, propertyKey, pd) {
- target._addWatch({bindTo: tplExpress, deep}, target[propertyKey])
- return target[propertyKey]
- }
- }
|