简体   繁体   中英

Angular2 init abstract class with object literal

export abstract class GridColumn {
    public field?: string;
    public sortField?: string;
    public header?: string;
    public footer?: string;
    public sortable?: any = true;
    public editable?: boolean = false;
    public filter?: boolean = true;
    public filterMatchMode?: string = 'contains';
    public filterPlaceholder?: string;
    public style?: any;
    public styleClass?: string;
    public hidden?: boolean = false;
    public selectionMode?: string = 'multiple';
    public frozen?: boolean;
}

For example doing this only returns a object with those defined properties.

private gridConf: GridColumn = <GridColumn>{
    field: "test2",
    header: "Test2",
    filter: true,
    filterMatchMode: "contains",
    filterPlaceholder: "Search from Test",
    sortable: true,
    selectionMode: "single"
};

What i want is a object of type GridColumn That has all the defined properties and all the default values.
This does not work:

private gridConf: GridColumn = GridColumn({
    field: "test2",
    header: "Test2",
    filter: true,
    filterMatchMode: "contains",
    filterPlaceholder: "Search from Test",
    sortable: true,
    selectionMode: "single"
});

Constructor would force me to write a long one and i would always have to add all properties in a specific order.

The end goal would be to use something like this that has all default and/or defined properties in any order:

private columns: Array<GridColumn> = [
    <GridColumn>{
        field: "test",
        selectionMode: "single",
        filter: true,
        filterMatchMode: "contains",
        filterPlaceholder: "Search from Test",
        sortable: true,
        header: "Test"

    },
    <GridColumn>{
        field: "test2",
        header: "Test2",
        filter: true,
        filterMatchMode: "contains",
        filterPlaceholder: "Search from Test",
        sortable: true,
        selectionMode: "single"
    }
];

Closest "hack" i could find was to remove abstract and add, where fields refers to itself:

public constructor(
    fields?: GridColumn) {
    if (fields) Object.assign(this, fields);
}

This is not really possible, but you could find a hacky way around it I suppose. Not saying this is best practice, but if you really really want it, this is how you can do it. FYI, default values are only initialised if you use new GridColumn() on a non abstract class:

GridColumn

export class GridColumn implements IGridColumn {

    public sortable: boolean = true;
    public editable: boolean = false;
    public filter: boolean = true;
    public filterMatchMode: string = 'contains';
    public hidden: boolean = false;
    public selectionMode: string = 'multiple';

    public field: string;
    public sortField: string;
    public header: string;
    public footer: string;
    public filterPlaceholder: string;
    public style: any;
    public styleClass: string;
    public frozen: boolean;

    constructor(data: IGridColumn = {}){
       Object.assign(this, data);
    }
}

IGridColumn

export interface IGridColumn {
    public field?: string;
    public sortField?: string;
    public header?: string;
    public footer?: string;
    public sortable?: boolean;
    public editable?: boolean;
    public filter?: boolean;
    public filterMatchMode?: string;
    public filterPlaceholder?: string;
    public style?: any;
    public styleClass?: string;
    public hidden?: boolean;
    public selectionMode?: string;
    public frozen?: boolean;
}

Usage

private columns: Array<GridColumn> = [
    new GridColumn(<IGridColumn>{
        field: "test",
        selectionMode: "single",
        filter: true,
        filterMatchMode: "contains",
        filterPlaceholder: "Search from Test",
        sortable: true,
        header: "Test"

    }),
    new GridColumn(<IGridColumn>{
        field: "test2",
        header: "Test2",
        filter: true,
        filterMatchMode: "contains",
        filterPlaceholder: "Search from Test",
        sortable: true,
        selectionMode: "single"
    })
];

Let me again stress that I believe that this is not best practice. Even naming an interface starting with an I is frowned upon :D

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM