1

で作成されたネストされたオブジェクトからクラスの関数にアクセスしたいのですが、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')ません! 。

4

1 に答える 1

3

Putting a field object (or any kind of non primitive value) on the class prototype like you are doing is a very bad idea. Every HistoryProperty you instantiate from the class will share that same field which is almost certainly not what you want.

Adding a accessor method for you field and creating it upon the first request allows you to call the yesterday method defined in your class and also makes sure you'll avoid any surprises that might occur with two instances of HistoryProperty sharing the same date fields.

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

With your current code, the HistoryProperty.yesterday method is not available when you are calling it because the class has not yet been defined and you are already trying to access a method on its prototype. Your expand listener handler probably won't work either, assuming the endDate field is created like StartDate. Those fields are on the prototype of the class and need to be accessed like this.

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

If you insist on putting the fields directly on your prototype (don't do this), you'll have to define your yesterday function before defining the class. For example.

(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()
        })
    });
} ()); 

Edit

When you are defining a class using Ext.define, this does not refer to your class prototype unless you are actually inside a class method.

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' 
    }
});

In your code, the source object literal is referring to this.yesterday and this.today. You cannot access yesterday or today at that point in the process of defining your class because this is still window.

One major issue is that you are using configurations that are meant for class instantiation but are specifying them at class definition time. If you look at Ext's docs for customEditors (which is deprecated), source, sourceConfig, etc. You'll see that they are adding these properties in the configuration object passed in to the constructor.

You don't really want to be adding those properties on the class prototype since they are instance specific and sharing your editor fields across multiple grids will cause a lot of unexpected behavior.

For example, if the start and end date fields are global, changing the start date in one grid will affect the minimum end date in every other grid that shares the fields.

Instead, override the initComponent method and add the config properties there. Something like this should work for you:

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;
    }
});
于 2013-03-03T14:02:48.157 に答える