Как динамически обновлять значения в шаблоне QWeb в odoo?

Я пытаюсь разработать модуль сканирования штрих-кода, чтобы производить инвентаризацию с помощью сканера штрих-кода. Я создал шаблон QWeb и визуализировал его с помощью метода this.$el.html, и я вижу, что это представление отображается соответствующим образом. Проблема в том, что значения, которые я передаю в шаблон, не обновляются действиями клиента. Как сделать так, чтобы они менялись динамически, когда я меняю их в js-скрипте? Код находится здесь:

barcode-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,
    };
});

transfer.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. Что я делаю неправильно? Должен ли я использовать какой-то другой подход для этого?


person vladkhard    schedule 05.12.2019    source источник


Ответы (1)


Вы должны создать действие, чтобы поймать событие при изменении вашего элемента.

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>
person norbertoonline    schedule 05.12.2019
comment
большое спасибо! Я думал, что есть несколько способов сделать это с помощью QWeb, но ваше решение вполне подходит - person vladkhard; 06.12.2019