odoo里视图模型MVC模式:

例子:在原来的视图上修改他:

var CustomRenderer = KanbanRenderer.extend({
....
});

var CustomRendererModel = KanbanModel.extend({
....
});

var CustomRendererController = KanbanController.extend({
....
});

var CustomDashboardView=KanbanView.extend({
config:_extend({},kanbanView.prototype.config,{
Model:customDashboardModel,
Renderer:customDashboardRenderer,
Controller:customDashboardController,
}),
});

var viewRegistry=require('web.view_registry');
viewRegistry.add('my_custom_view',CustomDashboardView);

最后在视图上引用
<field name="arch" type="xml">
<kanban js_class="my_custom_view">
.....
</kanban>
</field>

定义一个:m2m_group的视图:js部分

class ActWindowView(models.Model):
_inherit = 'ir.actions.act_window.view' view_mode =fields.Selection(selection_add=[('m2m_group','M2m_group')])
class View(models.Model):
_inherit = 'ir.ui.view' type = fields.Selection(selection_add=[('m2m_group', 'M2m Group')])
class Base(models.AbstractModel):
_inherit = 'base' @api.model
def get_m2m_group_data(self,domain,m2m_field):
records=self.search(domain)
result_dict={}
for record in records:
for m2m_record in record[m2m_field]:
if m2m_record.id not in result_dict:
result_dict[m2m_record.id]={
'name':m2m_record.display_name,
'children':[],
'model':m2m_record._name
}
result_dict[m2m_record.id]['children'].append({
'name':record.display_name,
'id':record.id,
})
return result_dict




odoo.define('m2m_group.Controller', function (require) {
'use strict'; var AbstractController = require('web.AbstractController');
var core = require('web.core');
var qweb = core.qweb; var M2mGroupController = AbstractController.extend({
custom_events: _.extend({}, AbstractController.prototype.custom_events, {
'btn_clicked': '_onBtnClicked',
}),
renderButtons: function ($node) {
if ($node) {
this.$buttons = $(qweb.render('ViewM2mGroup.buttons'));
this.$buttons.appendTo($node);
this.$buttons.on('click', 'button', this._onAddButtonClick.bind(this));
}
},
_onBtnClicked: function (ev) {
this.do_action({
type: 'ir.actions.act_window',
name: this.title,
res_model: this.modelName,
views: [[false, 'list'], [false, 'form']],
domain: ev.data.domain,
});
},
_onAddButtonClick: function (ev) {
this.do_action({
type: 'ir.actions.act_window',
name: this.title,
res_model: this.modelName,
views: [[false, 'form']],
target: 'new'
});
}, }); return M2mGroupController; });
odoo.define('m2m_group.Model', function (require) {
'use strict'; var AbstractModel = require('web.AbstractModel'); var M2mGroupModel = AbstractModel.extend({
get: function () {
return this.data;
},
load: function (params) {
this.modelName = params.modelName;
this.domain = params.domain;
this.m2m_field = params.m2m_field;
return this._fetchData();
},
reload: function (handle, params) {
if ('domain' in params) {
this.domain = params.domain;
}
return this._fetchData();
},
_fetchData: function () {
var self = this;
return this._rpc({
model: this.modelName,
method: 'get_m2m_group_data',
kwargs: {
domain: this.domain,
m2m_field: this.m2m_field
}
}).then(function (result) {
self.data = result;
});
},
}); return M2mGroupModel; });
odoo.define('m2m_group.Model', function (require) {
'use strict'; var AbstractModel = require('web.AbstractModel'); var M2mGroupModel = AbstractModel.extend({
get: function () {
return this.data;
},
load: function (params) {
this.modelName = params.modelName;
this.domain = params.domain;
this.m2m_field = params.m2m_field;
return this._fetchData();
},
reload: function (handle, params) {
if ('domain' in params) {
this.domain = params.domain;
}
return this._fetchData();
},
_fetchData: function () {
var self = this;
return this._rpc({
model: this.modelName,
method: 'get_m2m_group_data',
kwargs: {
domain: this.domain,
m2m_field: this.m2m_field
}
}).then(function (result) {
self.data = result;
});
},
}); return M2mGroupModel; });
odoo.define('m2m_group.View', function (require) {
'use strict'; var AbstractView = require('web.AbstractView');
var view_registry = require('web.view_registry');
var M2mGroupController = require('m2m_group.Controller');
var M2mGroupModel = require('m2m_group.Model');
var M2mGroupRenderer = require('m2m_group.Renderer'); var M2mGroupView = AbstractView.extend({
display_name: 'Author',
icon: 'fa-id-card-o',
config: {
Model: M2mGroupModel,
Controller: M2mGroupController,
Renderer: M2mGroupRenderer,
},
viewType: 'm2m_group',
groupable: false,
init: function (viewInfo, params) {
this._super.apply(this, arguments);
var attrs = this.arch.attrs; if (!attrs.m2m_field) {
throw new Error('M2m view has not defined "m2m_field" attribute.');
}
// Model Parameters
this.loadParams.m2m_field = attrs.m2m_field; },
}); view_registry.add('m2m_group', M2mGroupView); return M2mGroupView; });
<?xml version="1.0" encoding="utf-8" ?>
<templates > <t t-name="ViewM2mGroup">
<div class="row ml16 mr16">
<div t-foreach="groups" t-as="group" class="col-3">
<t t-set="group_data" t-value="groups[group]" />
<div class="card mt16">
<img class="card-img-top" t-attf-src="/web/image/#{group_data.model}/#{group}/image"/>
<div class="card-body">
<h5 class="card-title mt8"><t t-esc="group_data['name']"/></h5>
</div>
<ul class="list-group list-group-flush">
<t t-foreach="group_data['children']" t-as="child">
<li class="list-group-item"><i class="fa fa-book"/> <t t-esc="child.name"/></li>
</t>
</ul>
<div class="card-body">
<a href="#" class="btn btn-sm btn-primary o_primay_button" t-att-data-group="group">View books</a>
</div>
</div>
</div>
</div>
</t> <div t-name="ViewM2mGroup.buttons">
<button type="button" class="btn btn-primary">
Add Record
</button>
</div> <t t-name="FieldColorPills">
<t t-foreach="widget.totalColors" t-as="pill_no">
<span t-attr-class="o_color_pill o_color_#{pill_no} #{widget.value===pill_no and 'active' or ''}"
t-att-data-val="pill_no"
data-toggle="tooltip"
data-placement="top"
t-attf-title="This color is used in #{widget.colorGroupData[pill_no] or 0} books."
/> </t>
</t>
</templates>

<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_end" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script src="/auto_widget/static/src/js/auto_widget.js" type="text/javascript"/>
<link href="/auto_widget/static/src/scss/field_widget.scss" rel="stylesheet" type="text/scss" /> <script type="text/javascript" src="/auto_widget/static/src/js/m2m_group_view.js" />
<script type="text/javascript" src="/auto_widget/static/src/js/m2m_group_model.js" />
<script type="text/javascript" src="/auto_widget/static/src/js/m2m_group_controller.js" />
<script type="text/javascript" src="/auto_widget/static/src/js/m2m_group_renderer.js" /> </xpath>
</template>
</odoo>




ODOO里视图开发案例---定义一个像tree、form一样的视图的更多相关文章

  1. odoo里的开发案例

    1.模块命名[驼峰命名方法] res开头的是:resources   常见模型:res.users,   res.company,    res.partner,   res.config.setti ...

  2. iOS开发-自己定义重用机制给ScrollerView加入子视图

    事实上这个问题我非常早就想过,仅仅是没有通过去写程序实现,昨天有人提起,我就巧了一下 不知道大家打印郭tableview:cellforrow中cell初始的次数,也就是重用池中的cell个数.这个是 ...

  3. Java开发笔记(一百二十三)AWT图像视图

    前面介绍了AWT的几种基础控件,从按钮到文本标签,从输入框到选择框,无一例外都能显示文字,唯独无法显示某张图片文件.本以为AWT会提供专门的控件来显示图片,然而偏偏没有意料之中的图像控件,这可真是弱爆 ...

  4. ​ 用一个开发案例详解Oracle临时表

    ​ 用一个开发案例详解Oracle临时表 2016-11-14 bisal ITPUB  一.开发需求  最近有一个开发需求,大致需要先使用主表,或主表和几张子表关联查询出ID(主键)及一些主表字段 ...

  5. Android 让他们自己控制开发的定义(一个)

    作为一个创意开发.或软件UI设计要求比较高,你经常会遇到的情况来圣安德鲁斯控制不符合您的需求.这样的时候.件.同一时候.安卓也同意你去继承已经存在的控件或者实现你自己的控件以便优化界面和创造更加丰富的 ...

  6. iPhone开发中从一个视图跳到另一个视图有三种方法:

    iPhone开发中从一个视图跳到另一个视图有三种方法:   1.self.view addSubView:view .self.window addSubView,需要注意的是,这个方法只是把页面加在 ...

  7. CREATE VIEW - 定义一个视图

    SYNOPSIS CREATE [ OR REPLACE ] VIEW name [ ( column_name [, ...] ) ] AS query DESCRIPTION 描述 CREATE ...

  8. HTML5移动Web开发(六)——定义一个内容策略

    通过分析工具搜集到的数据,你可以定义一个内容策略,这对已经有了一个桌面网站的人是非常有用的. 1.确认你已经把分析工具的Javascript代码嵌入到网站中.(http://www.cnblogs.c ...

  9. 使用Jquery+EasyUI进行框架项目开发案例解说之中的一个---员工管理源代码分享

    使用Jquery+EasyUI 进行框架项目开发案例解说之中的一个 员工管理源代码分享 在開始解说之前,我们先来看一下什么是Jquery EasyUI?jQuery EasyUI是一组基于jQuery ...

随机推荐

  1. QT环境变量设置

    首先找到自己对应的目录 我的如图 还有一个路径 将这两个路径添加到系统变量的Path中

  2. 自动发布.NET Core Web应用

    1 原因和目的 相信很多开发者都需要将自己的编写的应用进行编译并部署到服务器上,这个过程在个人或小型团队的项目中都是一个简单的事情.但是对于并行化开发而言,就需要通过工具来辅助这个过程.于是,我参考了 ...

  3. 『居善地』接口测试 — 13、Moco框架的使用

    目录 1.Moco框架第一个练习 2.Get方法的Mock实现 3.Post方法的Mock实现 4.请求中加入Cookies 5.请求中加入Header 6.Moco模拟重定向 7.综合练习 8.总结 ...

  4. 09:CBV与settings

    CBV源码 # 切入点 url(r'^login/', views.Mylogin.as_view()) '''类名点名字还加括号 名字要么是绑定给类的方法 要么是无参函数''' ​ 1.as_vie ...

  5. Java @FunctionalInterface注解-6

    在学习 Lambda 表达式时,我们提到如果接口中只有一个抽象方法(可以包含多个默认方法或多个 static 方法),那么该接口就是函数式接口.@FunctionalInterface 就是用来指定某 ...

  6. csp-s模拟测试42「世界线·时间机器·密码」

    $t3$不会 世界线 题解 题目让求的就是每个点能到点的数量$-$出度 设每个点能到的点为$f[x]$ 则$f[x]=x \sum\limits_{y}^{y\in son[x]} U f[y]$ 用 ...

  7. Spring事件发布与监听机制

    我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. 目录 ...

  8. 2、SpringBoot整合之SpringBoot整合servlet

    SpringBoot整合servlet 一.创建SpringBoot项目,仅选择Web模块即可 二.在POM文件中添加依赖 <!-- 添加servlet依赖模块 --> <depen ...

  9. Linux定时任务-cronie

    1.cronie服务介绍 Linux crontab(cronie)是用来定期执行程序的命令. 当安装完成操作系统之后,默认就会启动此任务调度命令. crond 命令每分钟会定期检查是否有要执行的工作 ...

  10. Linux-Samba服务

    Samba服务 1.Samba的起源 对于windows的网上邻居来讲,共享文件的方式用的是SMB和CIFS协议以及NETBIOS协议Linux/Unix之间用的是NFS协议. 但是Linux和Win ...