2016-01-15 2 views
13

Ok поэтому сначала прочь вот мой очень простой JQuery плагинПреобразование плагин 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

Я пробовал несколько вещей, и ближайший я получил это.

машинопись

/// <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

Это то, что у меня есть на данный момент, и это работает

машинопись интерфейс JQuery { Greenify(); Greenify (опции: Coloring.GreenifyOptions); }

(function ($) 
{ 
    $.fn.Greenify = function (options) 
    { 
     return new Coloring.Greenify(this, options); 
    } 
})(jQuery); 

JQuery вар $ elems = $ ('A') Greenify (варианты).

Однако это означает, что я должен предоставить параметры, и если я создам конструктор без параметров, то я получаю опции неопределенными. Ответ, который я поставил правильно, верен для вопроса, который я задал. Однако только иметь в виду, что ответ при условии, что требуется вам предоставить варианты в вашем машинопись конструктор, я буду видеть, о том, как иметь параметры по умолчанию, а затем переопределить их в конструкторе, но это уже другой вопрос :)


Обновление 2

Просто чтобы все знали, что я нашел способ предоставить параметры вашему плагину или нет.

Что вы можете сделать это

класс машинопись

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); 
     } 

    } 

машинопись Интерфейс

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».

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

ответ

5

Вы может создать и ссылка ваш o файл WN определения greenify.d.ts и добавить функцию следующим образом:

interface Jquery { 
    greenify: (options: Coloring.IGreenifyOptions) => void 
} 

Тогда вы можете просто назвать это нравится:

$('a').greenify(new GreenifyOptions(...)); 

или

$('a').greenify({color:'', backgroundColor:''}); 

Объяснение:

В время ввода объединить все определения интерфейсов.

Side Примечание:

если вы непреклонны о том, как это точно $('a').Coloring.Greenify(..) тогда вам придется менять гораздо больше:

  • Окрашивание не мог быть имя вашего модуля больше, как вы 'd должен использовать его в определении интерфейса выше
  • Возможно, вам придется создать класс, который имеет .Greenify как статический метод
  • Возможно, больше ...

В целом, вероятно, легче придерживаться моего первоначального решения, поскольку оно немного менее подробное, но это зависит от вас.

Надежда, что помогает

Update:

Для учета опций по умолчанию можно изменить определение интерфейса, чтобы иметь переопределение:

interface Jquery { 
    greenify:() => void; 
    greenify: (options: Coloring.IGreenifyOptions) => void; 
} 

interface IGreenifyOptions 
{ 
    color?: string; 
    backgroundColor?: string; 
} 
+0

Это то, что у меня есть на данный момент, но это означает, что я должен предоставить параметры, но что, если бы я хотел использовать параметры по умолчанию? – Canvas

+0

Разве плагин jquery в верхней части вашего вопроса уже обрабатывает значения по умолчанию? если они являются значениями по умолчанию, которые вы имеете в виду, тогда это должно быть достаточно простым, чтобы добавить другое определение в интерфейс. См. Мое обновление – jsonmurphy

+0

Это так, но, например, можно сказать, что мы хотим изменить фоновый цвет, но не цвет, как бы это сделать в конструкторе? – Canvas

7

Создание JQuery плагинов вместе с машинопись может получить немного грязный. Я лично предпочитаю поддерживать синтаксис цепочки плагинов 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' 
    }); 
}); 

Demo

+0

Этот ответ выглядит многообещающим, однако у меня есть использовать расширение? могу ли я не просто предоставить конструктор по умолчанию для параметров, а затем, если я перейду в опции, переопределите параметры? – Canvas

+0

@Canvas Конечно, вы можете играть и манипулировать этим образцом в соответствии с вашими потребностями. Имейте в виду, что вам нужно передать объект конструктору. Вот соответствующий квест о сопоставлении объектов: http://stackoverflow.com/questions/16793503/initializing-typescript-class-values-from-constructor – Theodore

+0

Можно было бы улучшить часть ответа. Параметры по умолчанию могут быть статическими (и, следовательно, также модифицируемыми). '$ .extend' изменит первый параметр, поэтому вам просто нужно использовать пустой объект в качестве целевого объекта:' var opts = $ .extend ({}, defaults, opts); '. Также обратите внимание, что исходный вопрос не требует накладных расходов на наличие «класса» для параметров. Простой объект будет работать, поскольку нет методов. –

Смежные вопросы