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. docker 自定义部署Springboot——依赖与代码分离部署

    第一步:执行mvn package 命令打出jar包,然后解压jar包,把lib放到服务器合适的目录下面 第二步:打出不带jar包的SpringBoot工程 首先配置pom.xml文件 <bui ...

  2. NOIP模拟测试9「随·单·题」

    liu_runda出的题,先$\%\%\%\%\%\%\%\%\%\%\%$为敬 随 考试时没有Qj 然后甚至没做,甚至没交 我不知道我怎么想的 这个题挺难改 你需要用到 循环矩阵快速幂,矩阵快速幂优 ...

  3. Mysql优化(出自官方文档) - 第七篇

    Mysql优化(出自官方文档) - 第七篇 目录 Mysql优化(出自官方文档) - 第七篇 Optimizing Data Change Statements 1 Optimizing INSERT ...

  4. DL基础补全计划(一)---线性回归及示例(Pytorch,平方损失)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  5. 美化terminal时碰到的问题- Set-Theme

    报错: 1 Set-Theme Set-Theme: The term 'Set-Theme' is not recognized as a name of a cmdlet, function, s ...

  6. 1、mysql基础入门(1)

    1.mysql基础入门: 1.1.数据库介绍:

  7. 基于Redis的分布式锁设计

    前言 基于Redis的分布式锁实现,原理很简单嘛:检测一下Key是否存在,不存在则Set Key,加锁成功,存在则加锁失败.对吗?这么简单吗? 如果你真这么想,那么你真的需要好好听我讲一下了.接下来, ...

  8. POJ 1681 高斯消元 枚举自由变元

    题目和poj1222差不多,但是解法有一定区别,1222只要求出任意一解,而本题需要求出最少翻转次数.所以需要枚举自由变元,变元数量为n,则枚举的次数为1<<n次 #include < ...

  9. php 扩展 rabbitmq popt

    首先是rabbitmq-c-master.tar.gz包, 可以访问https://github.com/alanxz/rabbitmq-c去下载最新的 wget https://github.com ...

  10. nginx开启tls1.2及一些注意问题

    因为http传输是明文,通过抓包很容易获取到报文, 所以现在很多站点都开启了https,HTTPS在HTTP的基础上加入了SSL协议,对传输的数据进行加密. 目前主流的ssl协议是tlsv1.2 ng ...