1

The documentation for creating custom Kendo widgets is good enough, and leads to something like:

declare var kendo: kendo;

// To be able to get types, we can express the widget as this interface
interface ICustomDatePicker {    
    options: () => kendo.ui.DatePickerOptions;
}

; (function ($:JQueryStatic, window:any, document:Document, undefined?) {
    var CustomDatePicker: ICustomDatePicker = (<any>kendo.ui.DatePicker).extend({
        init: function (element, options:kendo.ui.DatePickerOptions) {
            var self = this;            
            // base call to initialize widget
            (<any>kendo.ui.DatePicker).fn.init.call(self, element, options);
        },
        options: {
            // the name is what it will appear as off the kendo namespace (i.e. kendo.ui.CustomDatePicker). 
            // The jQuery plugin would be jQuery.fn.kendoCustomDatePicker.
            name: "CustomDatePicker"
        }
    });
    // This makes it work as a jQuery plugin
    (<any>kendo.ui).plugin(CustomDatePicker);
})(jQuery, window, document);

A typescript file with that above, let's me do things like: $("#datePicker").kendoCustomDatePicker({}); and it all works beautifully.

My question is, is there a better way to write this in class form? My original thought is this:

module Foo {
    class CustomDatePicker extends kendo.ui.DatePicker {
        constructor(element, options) {
            super(element, options);
        }
    }
    (<any>kendo.ui).plugin(CustomDatePicker);
}

But that doesn't work (when calling the same $("#datePicker").kendoCustomDatePicker({});. This Gist gets closer, but I think the syntax is a bit funky - that the class doesn't extend the control directly. Any ideas?

Update 1

Looking at this answer, I'm trying to find a way to clean up setting the options by having it IN the class. I've gotten the following to semi-work, though it breaks down for some options and not others:

constructor(element: Element, options?: kendo.ui.TimePickerOptions) {
    super(element, options);
    $.extend(this.options, <kendo.ui.TimePickerOptions>{
        format: "hh:mm tt",
        parseFormats: ["HH:mm", "hh:mm tt"]
    });
}

In this case, it respects that format and you can see it working. If you try and do the following:

$.extend(this.options, <kendo.ui.TimePickerOptions>{
    format: "hh:mm tt",
    parseFormats: ["HH:mm", "hh:mm tt"]
});

.. it doesn't work, doesn't parse the input at all.

4

1 回答 1

3

有一种方法,但我不能 100% 确定它是否称得上“不错”。这是我今天编写的一些代码并且有效:

class MyTreeView extends kendo.ui.TreeView
{
    constructor(element: Element, options?: kendo.ui.TreeViewOptions) {
        super(element, options);
    }

    static fn;
}

// kendo.ui.plugin relies on the fn.options.name to get the name of the widget
MyTreeView.fn = MyTreeView.prototype;
MyTreeView.fn.options.name = "MyTreeView";

// kendo.ui.plugin which comes with the Kendo TypeScript definitions doesn't include this overload
module kendo.ui {
    export declare function plugin(widget: any, register?: Object, prefix?: String);
}

// register the plugin
kendo.ui.plugin(MyTreeView);

// extend the jQuery interface with the plugin method (needed to be used later)
interface JQuery {
    kendoMyTreeView(options?: kendo.ui.TreeViewOptions): JQuery;
}

// use the plugin
$(function () {
    $("#content").kendoMyTreeView({
        dataSource: [
            {
                text: "Root",
                items: [
                    { text: "Child" }
                ]
            }
        ]
    });
});
于 2013-06-13T18:31:37.233 回答