从嵌套的创建对象访问已定义类的函数

时间:2013-03-02 20:00:19

标签: extjs extjs4

我想从它使用Ext.create创建的嵌套对象访问类的函数我无法使用它,因为它引用了创建的对象。

Ext.define('FM.view.HistoryProperty',{
extend: 'Ext.grid.property.Grid',
alias: 'widget.historyProperty',
title: 'History',
closable: false,
header: true,
layout: {
    type: 'vbox',
    align: 'left'
},
sortableColumns: false,
customEditors: {
    Vehicle: Ext.create('Ext.form.ComboBox',{
        store: Ext.create('FM.store.Vehicles',{}),
        editable : false,
        queryMode: 'local',
        displayField: 'vehiclename',
        valueField: 'vehicleid',
        id: 'vehicle'
    }),
    getStartDateField: function() {
        if (!this.startDate) {
            this.startDate = Ext.create('Ext.form.DateField',{
                format: 'y-m-d G:i',
                value : this.yesterday(),
                listeners: {
                    expand: {
                        fn: function(field) {
                            field.setMaxValue(this.endDate.getValue());
                        },
                        scope: this
                    }
                }
            });
        }
        return this.startDate;
    } ,
    getEndDateField: function(){
        if(!this.endDate){
            this.endDate = Ext.create('Ext.form.DateField',{
                format: 'y-m-d G:i',
                selectOnFocus:true,
                value : this.today(),
                listeners: {
                    expand: {
                        fn: function(field){ field.setMinValue(this.startDate.getValue()); }
                    },
                    scope: this
                }
            });
        }
        return this.endDate;
    }
},
yesterday: function(){
    var yesterday = new Date();
    yesterday.setDate(yesterday.getDate()-1);
    yesterday.setHours(0,0,0);
    return yesterday;
},
today: function(){
    var today = new Date();
    today.setHours(23,59,59);
    return today;
},
source: {
    "Vehicle": 'Select Vehicle',
    "getStartDateField": this.yesterday,
    "getEndDateField": this.today
}

});

我使用已定义类的名称来访问它的函数,但它不起作用。而且Ext.cmp('historyProperty')不起作用!。

1 个答案:

答案 0 :(得分:3)

将一个字段对象(或任何类型的非原始值)放在类原型上就像你正在做的那样是一个非常糟糕的主意。您从类中实例化的每个HistoryProperty将共享相同的字段,这几乎肯定不是您想要的。

为您添加一个访问者方法并在第一次请求时创建它允许您调用类中定义的昨天方法,并确保您避免两个HistoryProperty实例可能出现的任何意外情况共享相同的日期字段。

Ext.define('FM.view.HistoryProperty',{
    extend: 'Ext.grid.property.Grid',
    alias: 'widget.historyProperty',

    getStartDateField: function() {
        if (!this.startDate) {
            this.startDate = Ext.create('Ext.form.DateField',{
                format: 'y-m-d G:i',
                value : this.yesterday(),
                listeners: {
                    expand: {
                        fn: function(field) {
                            field.setMaxValue(this.endDate.getValue());
                        },
                        scope: this
                    }
                }
            });
        }
        return this.startDate;
    },

    yesterday: function(){
        var yesterday = new Date();
        yesterday.setDate(yesterday.getDate()-1);
        yesterday.setHours(0,0,0);
        return yesterday;
    }
});

使用当前代码时,调用它时HistoryProperty.yesterday方法不可用,因为尚未定义类,并且您已尝试访问其原型上的方法。假设endDate字段是像StartDate一样创建的,那么您的展开侦听器处理程序可能也无法正常工作。这些字段在类的原型上,需要像这样访问。

function() {
    this.setMaxValue(FM.view.HistoryProperty.prototype.endDate.getValue());
}

如果你坚持将字段直接放在原型上(不要这样做),你必须在定义类之前定义你的昨天函数。例如。

(function() {
    var yesterday = function() {
        var date = new Date();
        date.setDate(date.getDate() - 1);
        date.setHours(0, 0, 0);
        return date;
    };

    Ext.define('FM.view.HistoryProperty',{
        extend: 'Ext.grid.property.Grid',
        alias: 'widget.historyProperty',
        StartDate: Ext.create('Ext.form.DateField',{
            format: 'y-m-d G:i',
            value : yesterday()
        })
    });
} ()); 

修改

使用Ext.define定义班级时,this不会引用您的班级原型,除非您实际上是在班级方法中。

Ext.define('Test', {
    doSomething: function() {
        // 'this' refers to the object this method was called on. An instantiation
        // of the Test class.
        this.x = 1; 
    }
    property1: 'a',
    // 'this' is the whatever scope Ext.define was called in (probably window), not Test.prototype.
    property2: this.property1, // property2 will not be 'a'
    objectProperty: {
        // 'this' is still window, not Test.prototype.
        property3: this.property1 // property3 will not be 'a' 
    }
});

在您的代码中,源对象文字指的是this.yesterdaythis.today。在定义您的课程时,您无法访问yesterdaytoday,因为this仍然是window

一个主要问题是您使用的是用于类实例化的配置,但是在类定义时指定它们。如果你看一下Ext的docs for customEditors(不推荐使用),source,sourceConfig等等。你会看到他们在传递给构造函数的配置对象中添加这些属性。

你真的不想在类原型上添加这些属性,因为它们是特定于实例的,并且跨多个网格共享编辑器字段会导致很多意外行为。

例如,如果开始日期和结束日期字段是全局字段,则更改一个网格中的开始日期将影响共享字段的每个其他网格中的最小结束日期。

相反,重写initComponent方法并在那里添加配置属性。这样的事情对你有用:

Ext.define('FM.view.HistoryProperty', {
    extend: 'Ext.grid.property.Grid',
    alias: 'widget.historyProperty',
    title: 'History',
    closable: false,
    header: true,
    layout: {
        type: 'vbox',
        align: 'left'
    },
    sortableColumns: false,

    getStartDateField: function() {
        if (!this.startField) {
            this.startField = Ext.create('Ext.form.DateField',{
                format: 'y-m-d G:i',
                listeners: {
                    expand: {
                        fn: function(field) {
                            // get this instance of the grid's end date field
                            field.setMaxValue(this.getEndDateField().getValue());
                        },
                        // the scope is the grid component.
                        scope: this
                    }
                }
            });
        }
        return this.startField;
    },

    getEndDateField: function() {
        if (!this.endField) {
            this.endField = Ext.create('Ext.form.DateField',{
                format: 'y-m-d G:i',
                listeners: {
                    expand: {
                        fn: function(field) {
                            // get this instance of the grid's start date field
                            field.setMinValue(this.getStartDateField().getValue());
                        },
                        // the scope is the grid component.
                        scope: this
                    }
                }
            });
        }
        return this.endField;
    },

    getVehicleField: function() {
        return Ext.create('Ext.form.ComboBox',{
            store: Ext.create('FM.store.Vehicles',{}),
            editable : false,
            queryMode: 'local',
            displayField: 'vehiclename',
            valueField: 'vehicleid',
            id: 'vehicle'
        });
    },

    // Setup the source and sourceConfig properties in initComponent not on the
    // class prototype so that each instance of the grid has its own unique
    // setup.
    initComponent: function() {
        // 'this' is the grid component.
        Ext.apply(this, {
            source: {
                Vehicle: "select vehicle",
                startDate: this.yesterday(),
                endDate: this.today()
            },
            sourceConfig: {
                startDate: {
                    displayName: 'Start',
                    // we are in a method so 'this' is the instance of the grid
                    // and the getStartDateField is available to us here.
                    editor: this.getStartDateField()   
                },
                endDate: {
                    displayName: 'End',
                    editor: this.getEndDateField()
                },
                Vehicle: {
                    displayName: 'Vehicle',
                    editor: this.getVehicleField()
                }
            }
        });

        this.callParent(arguments);
    },

    yesterday: function() {
        var yesterday = new Date();
        yesterday.setDate(yesterday.getDate()-1);
        yesterday.setHours(0,0,0);
        return yesterday;
    },

    today: function() {
        var today = new Date();
        today.setHours(23,59,59);
        return today;
    }
});