第十六章 服务混合类

服务混合类作为WC中基础服务提供类,提供了很多全局基础功能。

我们前面提到的模型类也是继承自服务混合类,因此本章所介绍的功能在模型及其子模型中都可以直接使用。

var Model = Class.extend(mixins.EventDispatcherMixin, ServicesMixin, {
    ...
}

RPC服务

服务混合类提供的重要功能之一就是为模型提供RPC接口,模型可以直接使用_rpc方法调用odoo的RPC服务接口。

_rpc: function (params, options) {
    var query = rpc.buildQuery(params);
    var prom = this.call('ajax', 'rpc', query.route, query.params, options, this);
    if (!prom) {
        prom = new Promise(function () {});
        prom.abort = function () {};
    }
    var abort = prom.abort ? prom.abort : prom.reject;
    if (!abort) {
        throw new Error("a rpc promise should always have a reject function");
    }
    prom.abort = abort.bind(prom);
    return prom;
},

执行动作

服务混合类提供的另外一个重要的功能即提供了直接调用后台动作(ir.actions)的方法。

do_action: function (action, options) {
    var self = this;
    return new Promise(function (resolve, reject) {
        self.trigger_up('do_action', {
            action: action,
            options: options,
            on_success: resolve,
            on_fail: reject,
        });
    });
},

从do_action的定义中可以看出来,其原理是用了trigger_up方法调用了do_action事件。

flags

在ir.actions.act_window中存在一个特殊的字段flags, 该字段并不是一个真实的字段, 只是用来在后端配置传递参数到前端页面的一个控制变量.

这点我们可以从flags在WC中的定义可以看出:

function _getActionInfo(action, props) {
    return {
        props: Object.assign({}, props, { action, actionId: action.id }),
        config: {
            actionId: action.id,
            actionType: action.type,
            actionFlags: action.flags,
            displayName: action.display_name || action.name || "",
            views: action.views,
        },
    };
}

WC将后台传递过来的flags参数赋值给action的actionFlags属性, 然后在渲染视图的时候将actionFlags属性传递给前端视图的构造函数, 从而达到控制视图的目的.

 this.viewParams = Object.assign({}, actionFlags, {
    action,
    // legacy views automatically add the last part of the breadcrumbs
    breadcrumbs: breadcrumbsToLegacy(breadcrumbs),
    modelName: this.props.resModel,
    currentId: this.props.resId,
    controllerState: {
        currentId:
            "resId" in this.props
                ? this.props.resId
                : this.props.state && this.props.state.currentId,
        resIds: this.props.resIds || resIds,
        searchModel,
        searchPanel,
    },
});

可以将flags理解为WC给后台留的一个隐秘的"武器", 这个"武器"并没有在后端的"武器库"中注册,但是却可以在返回动作中实现对前台视图元素的控制.

这里简单举一个案例用法, 笔者在给上海某BPM公司开发任务管理系统时碰到了下面一个需求, 要求用户在单机列表视图中的查看任务按钮时,弹出的FORM窗口不能显示创建和取消按钮.

很显然,我们需要在按钮的返回动作中返回一个FORM窗体, 但是问题在于如何控制创建和取消按钮的显示, 答案就是使用flags参数,将defaultButtons参数设置为False

return {
    "type": "ir.actions.act_window",
    "name": "任务反馈汇总",
    "view_mode":"form",
    "res_model":"k2.worklog.wizard",
    "res_id": wizard.id,
    "views":[(self.env.ref("k2_project.view_worklogs_wizard_form").id,"form")],
    "flags":{
        "form":{
            "default_buttons": False
        }
    },
    "target":"new"
}

results matching ""

    No results matching ""