《基于Modern工具包的本地化方式》的错误修正

Posted 上将军

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《基于Modern工具包的本地化方式》的错误修正相关的知识,希望对你有一定的参考价值。

在《基于Modern工具包的本地化方式》一文中实现的本地化方式忽略了在切换语言后,原始的文本值已经改变,要想再切换回去,由于找不到对应的本地化值,最终切换不了,因而,必须在第一次切换的时候记录下原始文本值,这样才能保证每次切换的时候都能找到对应值。

在前文中还有一个bug是当本地化先于组件完成初始化时,就不会监听localizedready事件。
本文还添加了语言切换按钮,用于切换语言。
以下是修正后的代码:
Localized.js

Ext.define('CommonShared.service.Localized', 
    alternateClassName: 'LocalizedService',
    singleton: true,

    config:
        currentLanguage: null
    ,

    requires:[
        'CommonShared.util.Url',
        'CommonShared.service.OAuth',
    ],
  
    isReady: false,

    constructor(config)
        const me = this;
        me.initConfig(config)
        me.initLanguages();
        me.loadResources();
    ,

    initLanguages()
        const me = this;
        let current = StorageService.get('lang');
        if(current) return;
        current = AppConfig.lang === 'zh-CN' ? 'zh-Hans' 
            : AppConfig.lang === 'zh-TW' ? 'zh-Hant' : AppConfig.lang;
        me.setCurrentLanguage(current);
        StorageService.set('lang', current);
    ,

    loadResources()
        const me= this;
        me.isReady = false;
        Ext.Ajax.request(
            url: URI.get('Configuration', 'localization'),
            headers: AuthService.getAuthorizationHeader(),
            scope: me
        ).then(me.loadSuccess, me.loadFailure, null, me);
    ,

    loadSuccess(response)
        const me = this,
            obj = Ext.decode(response.responseText,true);        
        if(obj)
            me.remoteRawValue = ;
            Object.assign(me.remoteRawValue, obj);
            me.doOverride();
        
        me.isReady = true;
        Ext.fireEvent('localizedready', me);

    ,

    loadFailure(response)
        let obj  = Ext.decode(response.responseText, true),
            error = 'Unknown Error!';
        if(obj && obj.error) error = obj.error;
        Ext.Msg.alert('Error', error);
    ,

    get(key, resourceName)
        const me = this,
            defaultResourceName = me.remoteRawValue.defaultResourceName,
            values = me.remoteRawValue.values;
        return resourceName && values[resourceName] && values[resourceName][key] 
            || ( values['ExtResource'] && values['ExtResource'][key] )
            || ( values[defaultResourceName] && values[defaultResourceName][key] )
            || key;
    ,

    getLanguages()
        return this.remoteRawValue.languages;
    ,

    getCurrentCulture()
        return this.remoteRawValue.currentCulture;
    ,

    switchLanguages(value)
        const me = this, 
            current = me.getCurrentLanguage();
        if(current === value) return;
        me.setCurrentLanguage(value);
        StorageService.set('lang', value);
        me.loadResources();
    ,

    localized(cls, name,  resourceName)
        name = Ext.String.capitalize(name);
        const originLocalized = cls.getOriginLocalized(),
            get = cls[`get$name`],
            set = cls[`set$name`];
        let value = originLocalized[name];
        //有原始值的,使用原始值返回
        if(value)
            if(set)
                set.apply(cls, [LocalizedService.get(value,resourceName)]);
                return;
            
            return LocalizedService.get(value,resourceName);
        
        //没有原始值的处理
        if(!get || !set) 
            //没有set或get方法的,直接返回
            value = name;
            originLocalized[name] = value;
            return LocalizedService.get(value,resourceName);
        ;
        value = get.apply(cls);
        originLocalized[name] = value;
        if(!value) return;
        set.apply(cls, [LocalizedService.get(value,resourceName)]);
    ,


    privates:
        remoteRawValue: ,

        doOverride()
            const me = this,
                values = me.remoteRawValue.values.ExtResource,
                newMonthNames = [],
                newDayNames = [],
                am = values['AM'] || 'AM',
                pm = values['PM'] || 'PM';
            if(!Ext.Date.originMonthNames)Ext.Date.originMonthNames = [].concat(Ext.Date.monthNames);
            Ext.Date.originMonthNames.forEach(month=>
                newMonthNames.push(values[month] || month);

            );
            Ext.Date.monthNames = newMonthNames;

            if(!Ext.Date.originDayNames)Ext.Date.originDayNames = [].concat(Ext.Date.dayNames);
            Ext.Date.originDayNames.forEach(day=>
                newDayNames.push(values[day] || day);

            );
            Ext.Date.dayNames = newDayNames;

            //console.log(Ext.Date)
            Ext.Date.formatCodes.a = `(this.getHours() < 12 ? '$am' : '$pm')`;
            Ext.Date.formatCodes.A = `(this.getHours() < 12 ? '$am' : '$pm')`;
    
            const parseCodes = 
                g: 1,
                c: "if (/(" + am + ")/i.test(results[0])) \\n" +
                    "if (!h || h == 12)  h = 0; \\n" +
                    " else  if (!h || h < 12)  h = (h || 0) + 12; ",
                s: `($am|$pm)`,
                calcAtEnd: true
            ;
    
            Ext.Date.parseCodes.a = Ext.Date.parseCodes.A = parseCodes;
    
    
        ,
    


)

Component.js

Ext.define('CommonOverrides.shared.Component',
    override: 'Ext.Component',

    config:
        resourceName: null,
        localized: [],
        originLocalized: 
    ,

    initialize()
        const me = this;
        me.callParent(arguments);
        if(LocalizedService && LocalizedService.isReady)
            me.onLocalized();
        
        Ext.on('localizedready', me.onLocalized, me);
    ,

    onLocalized()
        const me = this,
            xtype = me.xtype,
            resourceName = me.getResourceName(),
            service = LocalizedService,
            localized = me.getLocalized();
        if(me.isButton || me.isMenuItem) 
            service.localized(me, 'text');
            return;
        
        if(xtype === "loadmask")
            service.localized(me, 'message');
            return;
        ;
        if(me.isField)
            service.localized(me,'requiredMessage');
            service.localized(me,'validationMessage');
            service.localized(me,'label', resourceName);
            if(me.getPlaceholder) service.localized(me, 'placeholder', resourceName);
            if(me.getBoxLabel) service.localized(me ,'boxLabel', resourceName);
            if(xtype === 'datefield' || xtype === 'DatePicker')
                service.localized(me,'minDateMessage');
                service.localized(me,'maxDateMessage');
            
            if(xtype === 'numberfield')
                me.decimalsText = service.localized(me, 'decimalsText');
                me.minValueText = service.localized(me, 'minValueText');
                me.maxValueText = service.localized(me, 'maxValueText');
                me.badFormatMessage = service.localized(me, 'badFormatMessage');
            
            if(xtype === 'textfield')
                me.badFormatMessage = service.localized(me, 'badFormatMessage');
            
            me.setError(null);
            return;
        
        if(me.isContainer)
            if(me.isPanelTitle || me.isPanel) 
                service.localized(me , 'title', resourceName);
                if(xtype === 'tooltip')
                    service.localized(me , 'html', resourceName);
                
                const collapsible = me.getCollapsible && me.getCollapsible();
                if(collapsible)
                    service.localized(collapsible, 'collapseToolText');
                    service.localized(collapsible, 'expandToolText');
                
                me.doCustomLocalized(me, localized, resourceName);
                return;
            ;
            if(me.isGridColumn)                
                service.localized(me ,'text', resourceName);
                return;
            
            if(xtype === 'datepanel')
                service.localized(me, 'nextText');
                service.localized(me, 'prevText');
                return;
            
            if(me.isDataView)
                service.localized(me, 'loadingText');
                service.localized(me, 'emptyText');
                return;
            
            // if(xtype === 'lockedgridregion')
            //     service.localized(me, 'menuLabel');
            //     return;
            // 
        
        me.doCustomLocalized(me, localized, resourceName);
    ,

    doCustomLocalized(me, localized, resourceName)
        localized.forEach(key=>
            LocalizedService.localized(me, key, resourceName)
        );
    


)

Abstract.js

Ext.define('CommonOverrides.shared.plugin.Abstract',
    override: 'Ext.plugin.Abstract',

    config:
        originLocalized: 
    ,

    constructor: function(config) 
        const me = this;
        if (config) 
            me.cmp = config.cmp;
            me.pluginConfig = config;
            me.initConfig(config);
        
        if(LocalizedService && LocalizedService.isReady)
            me.onLocalized();
        
        Ext.on('localizedready', me.onLocalized, me);
    ,

    onLocalized()
        const me = this,
            type = me.type;
        if(type === 'gridrowdragdrop')
            me.dragText =  LocalizedService.localized(me , 'dragText');
            return
        ;
        if(type === 'listpaging')
            LocalizedService.localized(me , 'loadMoreText');
            LocalizedService.localized(me , 'noMoreRecordsText');
        
    ,

);

Validator.js

Ext.define('CommonOverrides.shared.data.validator.Validator',
    override: 'Ext.data.validator.Validator',

    config:
        originLocalized: 
    ,

    constructor: function(config) 
        const me = this;
        if (typeof config === 'function') 
            me.fnOnly = true;
            me.validate = config;
        
        else 
            me.initConfig(config);
        
        if(LocalizedService && LocalizedService.isReady)
            me.onLocalized();
        
        Ext.on('localizedready', me.onLocalized, me);
    ,

    onLocalized()
        const me = this,
            type = me.type,
             resourceName = 'ExtResource';
        if(type === 'bound' || type === 'length' || type === 'range')
            if(type === 'bound') LocalizedService.localized(me ,'emptyMessage',resourceName);
            if(type === 'range') LocalizedService.localized(me ,'nanMessage',resourceName);
            LocalizedService以上是关于《基于Modern工具包的本地化方式》的错误修正的主要内容,如果未能解决你的问题,请参考以下文章

基于Modern工具包的本地化方式(下)

《基于Modern工具包的本地化方式》的重构

内置的HTTP服务器Modern PHP

SharePoint Modern Page 的脚本引入部件

SharePoint Modern Page 的脚本引入部件

SharePoint Modern Page 的脚本引入部件