如何通过操作按钮呈现qweb模板?

huangapple go评论54阅读模式
英文:

How to render a qweb template by action button?

问题

我有一个Qweb模板,像这样:

<template id="test_template">
    <h1>我的模板</h1>
    <script type="text/javascript">
        console.log('它工作了');
    </script>
    <div>
        <t t-foreach="my_items" t-as="item">
            ...
        </t>
    </div>
</template>

我可以通过这样的控制器在网站上呈现它:

@http.route('/test_template', type="http", auth="user", methods=['GET'], website=True)
	def test_template(self, **kw):
		return request.render('my_module.test_template', {'my_items': [1, 2, 3]})

但我想要能够在框架本身直接呈现这个模板,而不是在单独的网站标签页中呈现,就像使用操作和视图一样。

如何通过操作按钮呈现qweb模板?

有什么想法,我该如何做到这一点?

英文:

I have Qweb template like this:

<template id="test_template">
    <h1>My template</h1>
    <script type="text/javascript">
        console.log('it works');
    </script>
    <div>
        <t t-foreach="my_items" t-as="item">
            ...
        </t>
    </div>
</template>

I can render it in website by a controller like this

@http.route('/test_template', type="http", auth="user", methods=['GET'], website=True)
	def test_template(self, **kw):
		return request.render('my_module.test_template', {'my_items': [1, 2, 3]})

but I want to be able to render this template not in a separate website tab, but in the framework itself directly, as it works with actions and views
如何通过操作按钮呈现qweb模板?

any ideas, how can I do this?

答案1

得分: 1

Odoo将<template>元素转换为<record>(在本例中为ir.ui.view),并不会在JavaScript qweb渲染器函数中可用。

您可以定义一个客户端操作并使用 _rpc 调用模型函数来渲染模板并返回结果。

示例: 调用 ir.ui.view 渲染模板函数

return self.env["ir.ui.view"]._render_template("my_module.test_template", 
    {'my_items': items}
)

编辑 添加自定义视图以渲染 QWEB

class ActWindowView(models.Model):
    _inherit = 'ir.actions.act_window.view'

    view_mode = fields.Selection(selection_add=[('qweb_view', "QWEB View")], ondelete={'qweb_view': 'cascade'})


class View(models.Model):
    _inherit = 'ir.ui.view'

    type = fields.Selection(selection_add=[('qweb_view', "QWEB View")], ondelete={'qweb_view': 'cascade'})

在清单文件的 assets/web.assets_backend 下添加以下 JavaScript 代码:

/** @odoo-module **/

import { Renderer, Controller, View } from 'web.qweb';
import registry from 'web.view_registry';

var QwebController = Controller.extend({
    init: function (parent, model, renderer, params) {
        params.withControlPanel = false;
        this._super.apply(this, arguments);
    },
});

var QwebRenderer = Renderer.extend({
    _render: function () {
        var self = this;
        return this._super.apply(this, arguments).then(function () {
            self.$el.html(self.state.body);
            $('head').append(self.$el.find('script'));
        });
    },
});

var QwebView = View.extend({
    config: _.extend({}, View.prototype.config, {
        Controller: QwebController,
        Renderer: QwebRenderer,
    }),
    viewType: 'qweb_view',
    groupable: false,
});

registry.add('qweb_view', QwebView);

定义一个 qweb_view 视图来调用您的模板并在窗口操作中使用它:

<record model="ir.ui.view" id="company_structure_test">
   <field name="name">company.structure.qweb</field>
   <field name="model">res.company</field>
   <field name="mode">primary</field>
   <field name="arch" type="xml">
       <qweb_view>
            <t t-call="qweb_view.company_structure_test_template">
                <t t-set="model" t-value="res_company"/&>
            </t>
        </qweb_view>
    </field>
</record>
        
<record id="action_company_structure" model="ir.actions.act_window">
    <field name="name">Структура компанії</field>
    <field name="res_model">res.company</field>
    <field name="view_mode">qweb_view</field>
    <field name="view_id" ref="company_structure_test"/>
</record>
英文:

Odoo transforms a <template> element into a <record> (ir.ui.view in this case) and will not be available to the JavaScript qweb renderer function.

You can define a client action and use _rpc to call a model function to render the template and return the result

Example: Call ir.ui.view render template function

return self.env["ir.ui.view"]._render_template("my_module.test_template", 
    {'my_items': items}
)

EDIT Add A custom view to render QWEB

class ActWindowView(models.Model):
    _inherit = 'ir.actions.act_window.view'

    view_mode = fields.Selection(selection_add=[('qweb_view', "QWEB View")], ondelete={'qweb_view': 'cascade'})


class View(models.Model):
    _inherit = 'ir.ui.view'

    type = fields.Selection(selection_add=[('qweb_view', "QWEB View")], ondelete={'qweb_view': 'cascade'})

Add the following JS code under assets/web.assets_backend in the manifest file:

/** @odoo-module **/

import { Renderer, Controller, View } from 'web.qweb';
import registry from 'web.view_registry';


var QwebController = Controller.extend({
    init: function (parent, model, renderer, params) {
        params.withControlPanel = false;
        this._super.apply(this, arguments);
    },
});

var QwebRenderer = Renderer.extend({
    _render: function () {
        var self = this;
        return this._super.apply(this, arguments).then(function () {
            self.$el.html(self.state.body);
            $('head').append(self.$el.find('script'));
        });
    },
});

var QwebView = View.extend({
    config: _.extend({}, View.prototype.config, {
        Controller: QwebController,
        Renderer: QwebRenderer,
    }),
    viewType: 'qweb_view',
    groupable: false,
});

registry.add('qweb_view', QwebView);

Define a qweb_view view to call your template and use it in the window action:

<record model="ir.ui.view" id="company_structure_test">
   <field name="name">company.structure.qweb</field>
   <field name="model">res.company</field>
   <field name="mode">primary</field>
   <field name="arch" type="xml">
       <qweb_view>
            <t t-call="qweb_view.company_structure_test_template">
                <t t-set="model" t-value="res_company"/>
            </t>
        </qweb_view>
    </field>
</record>
        
<record id="action_company_structure" model="ir.actions.act_window">
    <field name="name">Структура компанії</field>
    <field name="res_model">res.company</field>
    <field name="view_mode">qweb_view</field>
    <field name="view_id" ref="company_structure_test"/>
</record>

答案2

得分: 0

你需要继承设置视图 base.res_config_settings_view_form,如下所示:

<record id="res_config_settings_view_form" model="ir.ui.view">
  <field name="name">res.config.settings.view.form.inherit.account</field>
  <field name="model">res.config.settings</field>
  <field name="priority" eval="40"/>
  <field name="inherit_id" ref="base.res_config_settings_view_form"/>
  <field name="arch" type="xml">
    <xpath expr="//div[hasclass('settings')]" position="inside">
      <div class="app_settings_block" data-string="Invoicing" string="Invoicing" data-key="account" >
      
        <!-- 这里放置子视图的所有代码 -->

      </div>
    </xpath>
  </field>
</record>

如果还有其他需要翻译的部分,请提供具体内容。

英文:

you a typical view to be inherit the settings view base.res_config_settings_view_form. like the following:

<record id="res_config_settings_view_form" model="ir.ui.view">
  <field name="name">res.config.settings.view.form.inherit.account</field>
  <field name="model">res.config.settings</field>
  <field name="priority" eval="40"/>
  <field name="inherit_id" ref="base.res_config_settings_view_form"/>
  <field name="arch" type="xml">
    <xpath expr="//div[hasclass('settings')]" position="inside">
      <div class="app_settings_block" data-string="Invoicing" string="Invoicing" data-key="account" >
      
        <!-- Here all your code for sub-views -->


      </div>
    </xpath>
  </field>
</record>

答案3

得分: 0

Here is the translation of the text you provided:

"好的,大家,我花了差不多一个月的时间寻找解决方案,不幸的是,关于我尝试实现的内容,答案有些偏离,但最终我成功了。

我们可以使用 ir.actions.act_window 以 "qweb" 视图模式来完成这项任务。

<record id="action_company_structure" model="ir.actions.act_window">
    <field name="name">公司结构</field>
    <field name="res_model">res.company</field>
    <field name="view_mode">qweb</field>
    <field name="view_id" ref="tada.company_structure_test"/>
</record>

这是我的测试模板

<template id="company_structure_test">
    <h1>qweb 工作了</h1>
    <t t-set="test_data" t-value="model.get_company_structure_data()"/>
    <p t-esc="test_data"/>
    <p t-esc="test_data['test_str']"/>
    <p t-esc="test_data['test_list'][-1]"/>
    
    <script type="text/javascript">
        console.log('这不起作用');
    </script>
</template>

结果:
如何通过操作按钮呈现qweb模板?
我有印象它根本不应该起作用,但以某种方式在这种格式下它确实起作用。顶部的面板可以使用 JavaScript 脚本轻松隐藏,如果需要的话。

但是,如果你想要使用 JavaScript,就会出现问题。我尝试过,但它不起作用。当我使用 request.render('my_template',{}) 时遇到了相同的问题。如果在网站中呈现模板,JavaScript 起作用。如果在 Odoo 本身或空白页面上呈现,JavaScript 就不起作用,在浏览器控制台中没有 console.log。"

Please note that I've left the code parts in their original English since you requested not to translate the code.

英文:

ok guys, I spent almost a month searching for a solution, unfortunately the answers were a bit off about what I was trying to implement, but I got it at some point.

We can use ir.actions.act_window with "qweb" view_mode to get this job done.

&lt;record id=&quot;action_company_structure&quot; model=&quot;ir.actions.act_window&quot;&gt;
    &lt;field name=&quot;name&quot;&gt;Структура компанії&lt;/field&gt;
    &lt;field name=&quot;res_model&quot;&gt;res.company&lt;/field&gt;
    &lt;field name=&quot;view_mode&quot;&gt;qweb&lt;/field&gt;
    &lt;field name=&quot;view_id&quot; ref=&quot;tada.company_structure_test&quot;/&gt;
&lt;/record&gt;

here is my test template

&lt;template id=&quot;company_structure_test&quot;&gt;
    &lt;h1&gt;qweb works&lt;/h1&gt;
    &lt;t t-set=&quot;test_data&quot; t-value=&quot;model.get_company_structure_data()&quot;/&gt;
    &lt;p t-esc=&quot;test_data&quot;/&gt;
    &lt;p t-esc=&quot;test_data[&#39;test_str&#39;]&quot;/&gt;
    &lt;p t-esc=&quot;test_data[&#39;test_list&#39;][-1]&quot;/&gt;
    
    &lt;script type=&quot;text/javascript&quot;&gt;
        console.log(&#39;this don`t work&#39;);
    &lt;/script&gt;
&lt;/template&gt;

and result:
如何通过操作按钮呈现qweb模板?
I'm under the impression that it shouldn't work at all, but somehow it does in this format. The panel at the top can be simply hidden using a js script, if necessary

but there is a problem if you want to use js. I tried but it didn't work. i encountered the same problem when using request.render('my_template',{}). If you render your template in website, js works. If in odoo itself or on empty page, js didn`t work. there is no console.log in browser console.

huangapple
  • 本文由 发表于 2023年5月10日 19:00:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217610.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定