Подтвердить что ты не робот

Преобразование плагина 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".

Надеюсь, это поможет кому-то другому, у меня такая же проблема, как и я:)

4b9b3361

Ответ 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'
  });
});

Демо