zoukankan      html  css  js  c++  java
  • 16、手把手教你Extjs5(十六)Grid金额字段单位MVVM方式的选择

    这一节来完成Grid中的金额字段的金额单位的转换。转换旰使用MVVM特性,总体上和控制菜单的几种模式类似。首先在目录app/view/main/menu下建立文件Monetary.js,用于放金额单位的数据和生成菜单的items。

    /**
     * 金额单位的管理类
     */
    
    Ext.define('app.view.main.menu.Monetary', {
        statics: {
            values: null,
            getAllMonetary: function () {
                if (!this.values) {
                    // 初始化各种金额单位 元 千元 万元 百万元 亿元
                    this.values = new Ext.util.MixedCollection();
                    this.values.add('unit', this.createAMonetary('', 1, '元'));
                    this.values.add('thousand', this.createAMonetary('千', 1000, '千元'));
                    this.values.add('tenthousand', this.createAMonetary('万', 10000,
                                    '万元'));
                    this.values.add('million', this.createAMonetary('M', 100 * 10000,
                                    '百万元'));
                    this.values.add('hundredmillion', this.createAMonetary('亿', 10000
                                            * 10000, '亿元'));
                }
                return this.values;
            },
    
            // 生成菜单中的 items
            getMonetaryMenu: function () {
                var items = [];
                this.getAllMonetary().eachKey(function (key, item) {
                    items.push({
                        text: item.unitText,
                        value: key
                    })
                })
                return items;
            },
    
            createAMonetary: function (monetaryText, monetaryUnit, unitText) {
                return {
                    monetaryText: monetaryText, // 跟在数值后面的金额单位文字,如 100.00万
                    monetaryUnit: monetaryUnit, // 显示的数值需要除的分子
                    unitText: unitText  // 跟在字段后面的单位如 合同金额(万元)
                }
            },
    
            getMonetary: function (key) {
                return this.getAllMonetary().get(key);
            }
        }
    
    })

    在SettingMenu.js中加入菜单项

    {
        text : '金额单位',
        menu : [{
            xtype : 'segmentedbutton',
            reference : 'monetary',    // 加入了这一句,在改变数据的时候可以触发bind绑定的事件
            defaultUI : 'default',
            value : 'tenthousand',
            items : app.view.main.menu.Monetary.getMonetaryMenu()
        }]
    }

    生成的菜单如下:

    v5fu4snv

    在MainModels.js中的data属性下加入

    monetary : { // 金额单位
            value : 'tenthousand' // 默认万元,以后可以从后台取得个人偏好设置,或者存放在cookies中
    },

    在MainController.js中加入金额变更事件绑定和执行函数。

    init : function() {
    
        var vm = this.getView().getViewModel();
        // 绑定金额单位修改过后需要去执行的程序
        vm.bind('{monetary.value}', function(value) {
            this.onMonetaryChange(value);
        }, this)
    },
    
    // 金额单位修改过后执行
    onMonetaryChange : function(value) {
        console.log('金额单位变更:' + value);
        var m = app.view.main.menu.Monetary.getMonetary(value);
        Ext.monetaryText = m.monetaryText; // 设置当前的全局的金额单位
        Ext.monetaryUnit = m.monetaryUnit;
        Ext.each(this.getView().query('modulegrid'), function(grid) {
            if (grid.rendered) {
                grid.getView().refresh();
                Ext.Array.forEach(grid.columnManager.getColumns(), function(column) {
                    // 如果可以改变大小,并且是金额字段,则在改变了金额单位以后,自动调整一下列宽
                    if (!column.resizeDisabled && column.fieldDefine
                            && column.fieldDefine.tf_isCurrency) {
                        column.autoSize();
                    }
                })
            }
        });
    }

    绑定的时候也可以使用这种方法:

    vm.bind('{monetary.value}', 'onMonetaryChange', this);

    经过以上几个步骤,在上节的基础上就可以更改金额单位,并实时的刷新所有已经打开的Grid中的金额字段,刷新了以后还会对金额字段重新调整列宽。

    n5wnuh1q

    h4sxle0u

    zgyf2msl

    上面展示了转换过金额单位后金额字段的值的展示。事件的流转过程如下图:

    mygs1tg5

    对于Grid的column自动适应宽度,经过半天的研究,搞明白了一点,就是Renderer中,返回的应该是不加标签的值,具体的样式放在metaData中来定义。比如金额的Renderer函数修改为:(原来的函数看上一节)

    // 金额字段
    monetaryRenderer : function(val, metaData, model, row, col, store, gridview) {
        if (val) {
            if (Ext.monetaryUnit && Ext.monetaryUnit != 1)
                val = val / Ext.monetaryUnit;
            // 正数用蓝色显示,负数用红色显示,必须css和返回的值分开来设置,否则不能autoSize()
            metaData.style = 'color:' + (val > 0 ? 'blue' : 'red') + ';float:right;';
            return Ext.util.Format.number(val, '0,000.00') + Ext.monetaryText;
        } else
            return ''; // 如果为0,则不显示
    }

    原来把style的属性是放在返回的值里面的,这样在自动适应宽度的时候,extjs算不出到底有多宽,这样分开设置后,自动适应宽度就正常了。然后是在column的定义里面也要修改一下,不能用formatter,而要用renderer。例如对于整型的数据要改成这样:

    case 'Integer' :
        Ext.apply(field, {
            align : 'center',
            xtype : 'numbercolumn',
            format : '#',
            renderer : Ext.util.Format.intRenderer,
            // formatter : 'intRenderer',
            editor : {
                xtype : 'numberfield'
            }
        });
        break;
  • 相关阅读:
    【学习笔记】QT下载地址
    【学习笔记】激活码方式注册的实现原理述
    【学习笔记】Inputs on an Embedded Linux Device
    【学习笔记】TSlib校准原理
    【学习笔记】13.5 使用者的特殊 shell 与 PAM 模块
    【学习笔记】Linux GDM
    【学习笔记】MC.exe 生成H和RC文件
    【工具】时间差计算器
    【学习笔记】Android 学习(一)
    【学习笔记】tensor flow 2.4 moist 数据下载错误
  • 原文地址:https://www.cnblogs.com/niejunchan/p/4996972.html
Copyright © 2011-2022 走看看