/ / Definir um widget personalizado da UI do jQuery no TypeScript - jquery-ui, typescript

Definir um widget personalizado da IU do JQuery em TypeScript - jquery-ui, datilografado

No momento, estamos olhando para traduzir nosso projeto JavaScript para TypeScript. Nosso aplicativo depende muito de widgets personalizados da UI do jQuery.

Em nossa base de código atual, estamos usando um mecanismo de cópia profunda para herdar das definições de widget, permitindo, por exemplo, declarar um genérico TableWidget bem como um OrdersTableWidget que define funções mais específicas.

Portanto, gostaria de definir minhas definições de widget como classes TypeScript e vincular uma instância dessas classes ao jQuery.

Por exemplo

class MyWidget {
options: WidgetOptions;
_init(){
// general initialization
}
}

class MySecondWidget extends MyWidget {
_init(){
super._init();
// specific initialization
}
}

E depois

$.widget("MyNameSpace.MyWidget", new MyWidget());
$.widget("MyNameSpace.MySeWidget", new MyWidget());

Além disso, gostaria de denotar meus widgets personalizados como implementações de UIs do jQuery Widget definição

class MyWidget implements Widget {
options: WidgetOptions;
_init(){
// general initialization
}
}

para que eu possa usar a seguinte sintaxe no TypeScript:

$(selector).MyWidget(options);

Eu sei que tenho que trabalhar com o arquivo de definição (de Definitivamente Digitado), no entanto, ainda não encontrei uma fonte confiável que me explique como devo escrever os Widgets da UI do jQuery personalizados no TypeScript. Alguém tem experiência com isso?

Qualquer ajuda muito apreciada, como sempre!

Respostas:

13 para resposta № 1

Não sei se você pode escrever uma classe que implemente o Widget interface, devido à falta de construtores sobrecarregados. Você pode criar uma variável digitada pelo Widget interface.

Um plug-in jQuery padrão seria representado em JavaScript quase puro e não usaria módulos ou classes, pois acaba sendo agrupado como parte do jQuery, que por si só não é um módulo ou classe.

Aqui está um plugin vazio chamado plugin se parece com qualquer plug-in jQuery padrão, mas você pode ver que ele tira vantagem do sistema de tipos TypeScript e estende o JQuery interface para permitir que seja chamado.

/// <reference path="jquery.d.ts" />

interface JQuery {
plugin(): JQuery;
plugin(settings: Object): JQuery;
}

(function ($) {

function DoSomething(someParamater: string) : void {

}

$.fn.plugin = function (settings) {

var config = {
settingA: "Example",
settingB: 5
};

if (settings) {
$.extend(config, settings);
}

return this.each(function () {

});
};

})(jQuery);

Isso seria chamado da maneira normal.

$("#id").plugin();

Então, sério, minha resposta é - você realmente não podeo que você deseja, porque você está adicionando às interfaces declaradas para jQuery em vez de expô-las como módulos. Você pode agrupar o uso em um módulo, como um adaptador que abstrai o aspecto jQuery do uso em seu TypeScript, ou pode chamar suas classes de dentro do plug-in, mas o plug-in ou o widget não se encaixa realmente em um módulo ou classe.


4 para resposta № 2

Pode ser útil ter uma classe base em texto datilografadoa partir do qual outras classes de widget podem derivar. Seu único objetivo é fornecer a semântica da classe base para que você possa acessar os membros da classe base sem precisar recorrer à digitação fraca.

O truque é remover todos os membros em tempo de execução (no construtor) - caso contrário, você terá problemas com a herança fornecida pela fábrica de widgets. Por exemplo, o option O método substituiria o método original do widget, o que não é desejado: queremos apenas poder chamá-lo (de maneira estática).

class WidgetBase {

public element:JQuery;

constructor() {
// remove all members, they are only needed at compile time.
var myPrototype =  (<Function>WidgetBase).prototype;
$.each(myPrototype, (propertyName, value)=>{
delete myPrototype[propertyName];
});
}

/**
* Calles the base implementation of a method when called from a derived method.
* @private
*/
public _super(arg1?:any, arg2?:any, arg3?:any, arg4?:any) {

}

/**
* @private
*/
public _superApply(arguments) {

}

/**
* Gets or sets the value of the widget option associated with the specified optionName.
*/
public option(optionName:string, value?:any):any {

}

// ... further methods from http://api.jqueryui.com/jQuery.widget/
}

Então você pode implementar seu próprio widget como este:

class SmartWidget extends WidgetBase {

constructor(){
super();
}

public _create() {
var mySmartOption = this.option("smart"); // compiles because of base class
this.beSmart(mySmartOption);
}

public _setOption(key:string, value:any) {
if (key === "smart") {
this.beSmart(value);
}

this._super(key, value); // compiles because of base class
}

private beSmart(smartOne:any){
// ...
}

}

// register
jQuery.widget("myLib.smartWidget", new SmartWidget());

// assuming you are using https://github.com/borisyankov/DefinitelyTyped
declare interface JQuery{
smartWidget();
smartWidget(options:any);
smartWidget(methodName:string, param1?:any, param2?:any, param3?:any, param4?:any);
}

E, finalmente, você pode usar seu widget:

$(".selector").smartWidget({smart:"you"});