简体   繁体   English

将jQuery插件转换为TypeScript

[英]Converting a jQuery plugin to TypeScript

Ok so first off here is my very basic jQuery plugin 好吧首先,这是我非常基本的jQuery插件

(function ($){
    $.fn.greenify = function (options) {
        var settings = $.extend({
            // These are the defaults
            color: '#556b2f',
            backgroundColor: 'white'
        }, options);
}(jQuery));

$('a').greenify({
    color: 'orange'
}).showLinkLocation();

Basically all this does is change the text color and background-color with the provided element. 基本上所有这一切都是使用提供的元素更改文本颜色和背景颜色。 Now what I am trying to do is convert this simple plugin into TypeScript 现在我要做的是将这个简单的插件转换为TypeScript

I have tried a few things and the closest I got is this. 我尝试了一些东西,最接近的是这个。

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 which calls it 调用它的JQuery

$(function ()
{
    var options: Coloring.GreenifyOptions = new Coloring.GreenifyOptions('#0F0', '#000');

    var $elems = $('a');
    $elems.each(function()
    {
        var result = new Coloring.Greenify($(this), options)
    });
});

However I don't want to provide the element like the above new Coloring.Greenify($(this), options) , I basically want to do something like this 但是我不想提供像上面的new Coloring.Greenify($(this), options)的元素,我基本上想要做这样的事情

$('a').Coloring.Greenify(options);

or 要么

$('a').Coloring.Greenify(Coloring.GreenifyOptions()
{
    color: '#F0F',
    backgroundColor: '#FFF'
});

But I can't seem to figure how to tell TypeScript that the element it is attached to already is the Jquery element. 但我似乎无法想象如何告诉TypeScript它附加的元素已经是Jquery元素。 Could anyone shine some light on this to help me out. 任何人都可以对此有所启发,以帮助我。

PS the above I have works fine, I just want to change the calling code. PS以上我的工作正常,我只是想改变调用代码。


Update 更新

This is what I have at the moment and it works 这就是我现在所拥有的,它的工作原理

TypeScript interface JQuery { Greenify(); TypeScript接口JQuery {Greenify(); Greenify(options: Coloring.GreenifyOptions); Greenify(选项:Coloring.GreenifyOptions); } }

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

jQuery var $elems = $('a').Greenify(options); jQuery var $ elems = $('a')。绿化(选项);

However it means I have to provide options and if I do the constructor without options I get options is undefined. 然而,这意味着我必须提供选项,如果我没有选项的构造函数,我得到的选项是未定义的。 The answer I have ticked as correct is correct for the question I have asked. 我已经勾选的答案是正确的,这对我提出的问题是正确的。 However just keep in mind that the answer provided required you provide options into your typescript constructor, I am going to see on how to have default options and then override them in the constructor but this is a different question :) 但是请记住,提供的答案需要您在typescript构造函数中提供选项,我将看到如何使用默认选项,然后在构造函数中覆盖它们,但这是一个不同的问题:)


Update 2 更新2

Just to let everyone know I have found a way to provide options to your plugin or not. 只是为了让每个人都知道我找到了一种方法来为您的插件提供选项。

What you can do is this 你能做的就是这个

TypeScript class 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 TypeScript接口

interface JQuery
{
    Greenofy();
    Greenify(obj?: any);
    Greenify(options?: Coloring.GreenifyOptions);
}

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

jQuery code to call the plugin with one optional option 用一个可选选项调用插件的jQuery代码

$(function ()
{
    var $elems = $('a').Greenify(<Coloring.GreenifyOptions>{
        color: '#00F'
    });
});

So not the output will make the anchors background color '#00F' which is the default and the option I have provided will make the anchor text color '#00F'. 因此,输出不会使锚点背景颜色为“#00F”,这是默认设置,我提供的选项将使锚文本颜色为“#00F”。

I hope this helps anyone else that is having the same problem as me :) 我希望这能帮助其他与我有同样问题的人:)

Creating jQuery plugins along with TypeScript can get a bit messy. 与TypeScript一起创建jQuery插件可能会有点混乱。 I personally prefer keeping the jQuery plugin chaining syntax, mostly for consistency and maintainability . 我个人更喜欢保持jQuery插件链接语法,主要是为了保持一致性和可维护性。

So, after the module declaration you can basically wrap around your implementation extending the jQuery prototype as: 因此,在模块声明之后,您基本上可以将您的实现扩展为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);

Fetching the plugin as: 获取插件为:

$(function() {

  var $a = $('a').Coloring();
  var $div = $('div').Coloring({
    color: '#F0F',
    backgroundColor: '#FFF'
  });
  var $div = $('strong').Coloring({
    color: '#gold',
    backgroundColor: 'pink'
  });
});

Demo 演示

You can create and reference your own definitions file greenify.d.ts and add the function like this: 您可以创建和引用自己的定义文件greenify.d.ts并添加如下函数:

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

Then you can simple call it like: 然后你可以简单地称之为:

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

or 要么

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

Explanation: 说明:

At compile time typescript will actually merge all interface definitions. 在编译时,typescript将实际合并所有接口定义。

Side Note: 边注:

if you're adamant about having it exactly as $('a').Coloring.Greenify(..) then you'll have to change a lot more: 如果你坚持要完全像$('a').Coloring.Greenify(..)那么你将不得不改变更多:

  • Coloring couldnt be your module's name anymore as you'd have to use it in the interface definition above 着色不再是您模块的名称,因为您必须在上面的接口定义中使用它
  • You would probably have to create a class that has .Greenify as static method 您可能必须创建一个将.Greenify作为静态方法的类
  • Possibly more... 可能更多......

All in all it's probably easier to stick with my initial solution as it its a bit less verbose but that's up to you. 总而言之,我可能更容易坚持使用我的初始解决方案,因为它不那么冗长,但这取决于你。

Hope that helps 希望有所帮助

Update: 更新:

To account for the default options you can modify the interface definition to have overrides: 要考虑默认选项,您可以修改接口定义以进行覆盖:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM