如何动态更新odoo中QWeb模板中的值?

How to update values in QWeb template in odoo dynamically?

我正在尝试开发条码扫描模块以使用条码扫描仪进行库存转移。 我制作了 QWeb 模板并使用 this.$el.html 方法渲染它,我可以看到正确渲染的视图。问题是我传递给模板的值没有随着客户端操作而更新。当我在 js 脚本中更改它们时,如何使它们动态更改?代码在这里:

条码-scanner.js

odoo.define('stock.barcode_scanner', function(require) {
    'use sctrict';

    var AbstractAction = require('web.AbstractAction');
    var core = require('web.core');
    var QWeb = core.qweb;
    var _t = core._t;

    var BarcodeAction = AbstractAction.extend({

        start: function() {
            var self = this;
            self.$el.html(QWeb.render("BarcodeHandlerView", {widget: self}));
            core.bus.on('barcode_scanned', this, this._onBarcodeScanned);

            return this._super();
        },

        destroy: function () {
            core.bus.off('barcode_scanned', this, this._onBarcodeScanned);
            this._super();
        },

        _onBarcodeScanned: function(barcode) {
            var self = this;
            this._rpc({
                    model: 'stock.barcode.handler',
                    method: 'product_scan',
                    args: [barcode, ],
                })
                .then(function (result) {
                    if (result.action) {
                        var action = result.action;
                        if (action.type === 'source_location_set') {
                            self.sourceLocation = action.value;
                        } else if (action.type === 'product_added') {
                            if (self.productsList === undefined) {
                                self.productsList = [];
                            }
                            self.productsList.push(action.value);
                        } else if (action.type === 'destination_location_set') {
                            self.destionationLocation = action.value;
                        } else if (action.type === 'validation') {
                            self.sourceLocation = undefined;
                            self.productsList = undefined;
                            self.destinationLocation = undefined;
                        }
                    }
                    if (result.warning) {
                        self.do_warn(result.warning);
                    }
                });
        },
    });

    core.action_registry.add('stock_barcode_scanner', BarcodeAction);

    return {
        BarcodeAction: BarcodeAction,
    };
});

transfers.xml

<?xml version="1.0" encoding="utf-8"?>
<template id="theme.tp_remove_button"> 
    <t t-name="BarcodeHandlerView">
        <div>Source Location: <t t-esc="widget.sourceLocation"/></div>
        <div>Destination Location: <t t-esc="widget.destinationLocation"/></div>
    </t>
</template>

我确信 __manifest__.py 中的所有设置都正确 - 我可以看到视图,但客户端操作不会触发页面更新 - 当我触发它们时,客户端操作是 运行 -我可以从 python 函数中看到我 return 的警告。我究竟做错了什么?我应该使用其他方法来实现吗?

您必须创建一个动作以在您的元素更改时捕获事件。

odoo.define('stock.barcode_scanner', function(require) {
    'use sctrict';

     var AbstractAction = require('web.AbstractAction');
     var core = require('web.core');
     var QWeb = core.qweb;
     var _t = core._t;

     var BarcodeAction = AbstractAction.extend({

     // ***** Add this to catch events on your template
     events: {
        'change #destination-location': '_onBarcodeScanned',
     },

     start: function() {
        var self = this;
        self.$el.html(QWeb.render("BarcodeHandlerView", {widget: self}));
        core.bus.on('barcode_scanned', this, this._onBarcodeScanned);

        return this._super();
     },

     destroy: function () {
        core.bus.off('barcode_scanned', this, this._onBarcodeScanned);
        this._super();
     },

     action_change_destination: function (newLocation = null) {
        if(newLocation  === null){
            return null;
        }else{
            let self = this;
            console.log("My new awesome destination changing....");
            self.destinationLocation = newLocation;
            $("#detination-location").html(self.destinationLocation);
        } 
     },
     _onBarcodeScanned: function(barcode) {
         var self = this;
         this._rpc({
                model: 'stock.barcode.handler',
                method: 'product_scan',
                args: [barcode, ],
            })
            .then(function (result) {
                if (result.action) {
                    var action = result.action;
                    if (action.type === 'source_location_set') {
                        self.sourceLocation = action.value;
                    } else if (action.type === 'product_added') {
                        if (self.productsList === undefined) {
                            self.productsList = [];
                        }
                        self.productsList.push(action.value);
                    } else if (action.type === 'destination_location_set') {
                        self.destionationLocation = action.value;
                        // ****** GO AND CHANGE YOUR DESTINATION  *****
                        self.action_change_destination(self.destionationLocation);
                    } else if (action.type === 'validation') {
                        self.sourceLocation = undefined;
                        self.productsList = undefined;
                        self.destinationLocation = undefined;
                    }
                }
                if (result.warning) {
                    self.do_warn(result.warning);
                }
            });
    },
    });

    core.action_registry.add('stock_barcode_scanner', BarcodeAction);

   return {
       BarcodeAction: BarcodeAction,
   };
});

而在你看来应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<template id="theme.tp_remove_button"> 
<t t-name="BarcodeHandlerView">
       <div>Source Location: <t t-esc="widget.sourceLocation"/></div>
       <div>Destination Location: <span id="destination-location" /></div>
   </t>
</template>