Skip to content

UI fragments

Fragment 是一段 UI 代码段,用来在 UI template 中插入、删除和修改组件。其适用于在基于内置模板的基础上进行少量的 UI 自定义。

如果需要大量的自定义布局和设备自适应,请参考 Appearancelayout template 中描述的方法。

简单示例

以下的代码是使用 fragment 配置从 mobile 和 desktop/tablet 布局中移除 comment-tab 组件。点击 run 运行示例,您可以使用 Chrome DevTool 的 device mode 来模拟 mobile/tablet 的效果。

html
<script>
    var CustomAppearance= UIExtension.appearances.AdaptiveAppearance.extend({
        getDefaultFragments: function() {
            var isMobile = PDFViewCtrl.DeviceInfo.isMobile;
            if(isMobile) {
                // mobile 设备端的 Fragment 配资。
                return [{
                    target: 'comment-tab',
                    action: 'remove'
                },{
                    target: 'comment-tab-li',
                    action: 'remove'
                }, {
                    target: 'comment-tab-body',
                    action: 'remove'
                }];
            } else {
                // desktop/tablet 设备端的 Fragment 配资。
                return [{
                    target: 'comment-tab',
                    action: 'remove'
                }, {
                    target: 'fv--comment-tab-paddle',
                    action: 'remove'
                }, {
                    target: 'hand-tool',
                    config: {
                        callback: {
                            around: function(callback, args) {
                                try{
                                    console.info('before callback');
                                    var ret;
                                    if(callback instanceof UIExtension.Controller) {
                                        ret = callback.handle(...args);
                                    } else {
                                        ret = callback.apply(this, args);
                                    }
                                    console.info('after callback');
                                    return ret;
                                }catch(e) {
                                    console.error(e, 'an error occurred');
                                } finally {
                                    console.info('');
                                }
                            }
                        }
                    },
                }];
            }
        }
    });
    var libPath = window.top.location.origin + '/lib';

    var pdfui = new UIExtension.PDFUI({
            viewerOptions: {
                libPath: libPath,
                jr: {
                    licenseSN: licenseSN,
                    licenseKey: licenseKey
                }
            },
            renderTo: document.body,
            // 根据设备类型提供不同的 appearance。
            appearance: CustomAppearance,
            addons: []
    });
</script>
json
{
    "iframeOptions": {
        "style": "height: 500px",
        "injectCss": [
            "/lib/UIExtension.vw.css"
        ]
    }
}

Fragment 配置参数描述

  • target: 控件的名称, 每个控件的名称都是唯一的。
  • action: 表示这个片段的作用方式,默认为 UIExtension.UIConsts.FRAGMENT_ACTION.EXT。具体说明如下:
    • UIExtension.UIConsts.FRAGMENT_ACTION.EXT: 扩展目标控件。
    • UIExtension.UIConsts.FRAGMENT_ACTION.BEFORE: 在目标控件前插入控件。
    • UIExtension.UIConsts.FRAGMENT_ACTION.AFTER: 在目标控件后插入控件。
    • UIExtension.UIConsts.FRAGMENT_ACTION.APPEND: 将控件插入到目标控件,要求目标控件必须是容器类型的。
    • UIExtension.UIConsts.FRAGMENT_ACTION.FILL: 将目标控件的子空间全部清空并用新控件覆盖,要求目标控件必须是容器类型的。
    • UIExtension.UIConsts.FRAGMENT_ACTION.REPLACE: 将目标控件替换为新控件。
    • UIExtension.UIConsts.FRAGMENT_ACTION.REMOVE: 删除目标控件。
  • template: 控件模版。其内容为 XML 格式,action 为 BEFORE/AFTER/APPEND/FILL/REPLACE。
  • config: 控件配置对象,action 为 REMOVE 时无效。
    • config.target: 模板中控件的名称,只有当 action 为 BEFORE/AFTER/APPEND/FILL/REPLACE 时需要用到。

    • config.attrs: 设置控件的 html 属性。

    • config.callback: 控件的业务逻辑实现, 有以下三种写法:

      • function: 控件的事件会调用到这个函数,而且会覆盖内置回调。支持 function 的基础组件只有 (xbutton、dropdown-button 和context-menu-item) 。如果要基于内置回调添加功能,可以用第二种方法。

      • controller class: Controller 类可以监听组件生命周期以及处理更多的组件事件:

        javascript
        {
            target: 'hand-tool',
            config: {
                callback: class extends UIExtension.Controller {
                    mounted() {
                        super.mounted();
                        this.component.element.addEventListener('hover', e => {
                            console.info('mouse over', this.component)
                        })
                    }
                    handle() {
                        console.info('hand-tool clicked')
                    }
                }
            }
        }
      • decorator object: 包含了一系列用于拦截 controller handle 方法执行的函数钩子,包括 before, after, thrown 以及 around。

        javascript
        {
            target: 'hand-tool',
            config: {
                callback: {
                    before: function() {
                        // 在controller handle 方法调用之前执行的函数, 它可以接收到 handle 函数的所有参数。
                    },
                    after: function(returnValue) {
                        // 在 controller handle 方法调用之后执行的函数,它可以接收到 handle 函数返回值以及调用参数。
                    },
                    thrown: function(error) {
                        // 在 controller handle 方法抛出异常之后执行的函数,它可以接收到异常对象以及调用参数。
                    },
                    around: function(callback, args) {
                        // 接收 controller handle 方法引用以及调用参数,在 around 回调中,可以对 handle 方法运行前后以及在捕获异常的代码块中执行代码。并且还可以决定是否执行 handle 方法。
        
                        try{
                            console.info('before callback');
                            var ret;
                            if(callback instanceof UIExtension.Controller) {
                                ret = callback.handle(...args);
                            } else {
                                ret = callback.apply(this, args);
                            }
                            console.info('after callback');
                            return ret;
                        }catch(e) {
                            console.error(e, 'an error occurred');
                        } finally {
                            console.info('');
                        }
                    }
                }
            }
        }

注意事项

建议 fragment 仅用于对 UI 进行微调。如果对内置布局修改比较大,请参阅 Appearancelayout template 小节中描述的方法。