Преобразование плагина jQuery в TypeScript
Хорошо, так что сначала мой очень простой плагин jQuery
(function ($){
$.fn.greenify = function (options) {
var settings = $.extend({
// These are the defaults
color: '#556b2f',
backgroundColor: 'white'
}, options);
}(jQuery));
$('a').greenify({
color: 'orange'
}).showLinkLocation();
В основном все это означает изменение цвета текста и фона с предоставленным элементом. Теперь я пытаюсь преобразовать этот простой плагин в TypeScript
Я пробовал несколько вещей, и ближе всего я получил это.
TypeScript
/// <reference path="../../typings/jquery/jquery.d.ts" />
module Coloring
{
interface IGreenifyOptions
{
color: string;
backgroundColor: string;
}
export class GreenifyOptions implements IGreenifyOptions
{
// Fields
color: string;
backgroundColor: string;
constructor(color: string, backgroundColor: string)
{
this.color = color;
this.backgroundColor = backgroundColor;
}
}
export class Greenify
{
// Fields
element: JQuery;
options: GreenifyOptions;
constructor(element: JQuery, options: GreenifyOptions)
{
this.element = element;
this.options = options;
this.OnCreate();
}
OnCreate()
{
this.element.css('color', this.options.color).css('background-color', this.options.backgroundColor);
}
}
}
JQuery, который вызывает его
$(function ()
{
var options: Coloring.GreenifyOptions = new Coloring.GreenifyOptions('#0F0', '#000');
var $elems = $('a');
$elems.each(function()
{
var result = new Coloring.Greenify($(this), options)
});
});
Однако я не хочу предоставлять элемент, подобный выше new Coloring.Greenify($(this), options)
, я в основном хочу сделать что-то вроде этого
$('a').Coloring.Greenify(options);
или
$('a').Coloring.Greenify(Coloring.GreenifyOptions()
{
color: '#F0F',
backgroundColor: '#FFF'
});
Но я не могу представить, как сказать TypeScript, что к элементу, к которому он привязан уже, относится элемент Jquery
. Может ли кто-нибудь осветить этот свет, чтобы помочь мне.
P.S. выше я работаю хорошо, я просто хочу изменить код вызова.
Update
Это то, что у меня есть на данный момент, и оно работает
TypeScript интерфейс JQuery { Greenify(); Greenify (варианты: Coloring.GreenifyOptions); }
(function ($)
{
$.fn.Greenify = function (options)
{
return new Coloring.Greenify(this, options);
}
})(jQuery);
JQuery
var $elems = $('a'). Greenify (опции);
Однако это означает, что я должен предоставить параметры, и если я создаю конструктор без параметров, я получаю опции undefined. Ответ, который я поставил правильно, верен для вопроса, который я задал. Однако просто имейте в виду, что предоставленный ответ потребовал, чтобы вы предоставили опции в свой конструктор TypeScript, я собираюсь посмотреть, как иметь параметры по умолчанию, а затем переопределять их в конструкторе, но это другой вопрос:)
Обновление 2
Просто чтобы все знали, что я нашел способ предоставить параметры вашему плагину или нет.
Что вы можете сделать, это
TypeScript класс
export class Greenify
{
// Default Options
static defaultOptions: IGreenifyOptions =
{
color: '#F00',
backgroundColor: '#00F'
};
// Fields
element: JQuery;
options: GreenifyOptions;
constructor(element: JQuery, options: GreenifyOptions)
{
// Merge options
var mergedOptions: GreenifyOptions = $.extend(Greenify.defaultOptions, options);
this.options = mergedOptions;
this.element = element;
this.OnCreate();
}
OnCreate()
{
this.element.css('color', this.options.color).css('background-color', this.options.backgroundColor);
}
}
TypeScript Интерфейс
interface JQuery
{
Greenofy();
Greenify(obj?: any);
Greenify(options?: Coloring.GreenifyOptions);
}
(function ($)
{
$.fn.Greenify = function (options)
{
return new Coloring.Greenify(this, options);
}
})(jQuery);
Код jQuery для вызова плагина с одним необязательным параметром
$(function ()
{
var $elems = $('a').Greenify(<Coloring.GreenifyOptions>{
color: '#00F'
});
});
Таким образом, вывод не приведет к тому, что цвет фона якорей "# 00F", который является значением по умолчанию, и предоставленная мной опция сделает цвет текста якоря "# 00F".
Надеюсь, это поможет кому-то другому, у меня такая же проблема, как и я:)
Ответы
Ответ 1
Вы можете создать и ссылку свой собственный файл определений greenify.d.ts
и добавить функцию следующим образом:
interface Jquery {
greenify: (options: Coloring.IGreenifyOptions) => void
}
Затем вы можете просто называть его следующим:
$('a').greenify(new GreenifyOptions(...));
или
$('a').greenify({color:'', backgroundColor:''});
Объяснение:
Во время компиляции typescript фактически объединит все определения интерфейсов.
Боковое примечание:
если вы непреклонны в том, чтобы иметь его точно как $('a').Coloring.Greenify(..)
, вам придется изменить намного больше:
- Раскраска не может быть вашим именем модуля больше, поскольку вам придется использовать его в определении интерфейса выше
- Вам, вероятно, придется создать класс, который имеет .Greenify как статический метод
- Возможно, больше...
В целом это, вероятно, проще придерживаться моего первоначального решения, так как оно немного менее подробное, но это зависит от вас.
Надеюсь, что поможет
Update:
Для учета параметров по умолчанию вы можете изменить определение интерфейса для переопределения:
interface Jquery {
greenify: () => void;
greenify: (options: Coloring.IGreenifyOptions) => void;
}
interface IGreenifyOptions
{
color?: string;
backgroundColor?: string;
}
Ответ 2
Создание плагинов jQuery вместе с TypeScript может стать немного беспорядочным. Я лично предпочитаю поддерживать синтаксис цепочки плагинов jQuery, в основном для обеспечения согласованности и удобства обслуживания.
Итак, после объявления модуля вы можете в основном обернуть вокруг своей реализации расширение прототипа jQuery как:
module Coloring {
interface IGreenifyOptions {
color: string;
backgroundColor: string;
}
export class GreenifyOptions implements IGreenifyOptions {
// Fields
color: string;
backgroundColor: string;
constructor(color: string, backgroundColor: string) {
this.color = color;
this.backgroundColor = backgroundColor;
}
}
export class Greenify {
// Fields
element: JQuery;
options: GreenifyOptions;
constructor(element: JQuery, options: GreenifyOptions) {
this.element = element;
this.options = options;
this.OnCreate();
}
OnCreate() {
this.element.css('color', this.options.color).css('background-color', this.options.backgroundColor);
}
}
}
//jquery plugin wrapper.
;
(function(w, $) {
//no jQuery around
if (!$) return false;
$.fn.extend({
Coloring: function(opts) {
//defaults
var defaults: Coloring.GreenifyOptions = new Coloring.GreenifyOptions('#0F0', '#000');
//extend the defaults!
var opts = $.extend({}, defaults, opts)
return this.each(function() {
var o = opts;
var obj = $(this);
new Coloring.Greenify(obj, o);
});
}
});
})(window, jQuery);
Получение плагина как:
$(function() {
var $a = $('a').Coloring();
var $div = $('div').Coloring({
color: '#F0F',
backgroundColor: '#FFF'
});
var $div = $('strong').Coloring({
color: '#gold',
backgroundColor: 'pink'
});
});
Демо