将 jQuery 插件转换为 TypeScript
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34811716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting a jQuery plugin to TypeScript
提问by Canvas
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. Could anyone shine some light on this to help me out.
但我似乎无法弄清楚如何告诉 TypeScript 它所附加的Jquery
元素已经是该元素。任何人都可以对此有所了解以帮助我。
P.S. 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();
Greenify(options: Coloring.GreenifyOptions);
}
(function ($)
{
$.fn.Greenify = function (options)
{
return new Coloring.Greenify(this, options);
}
})(jQuery);
jQuery
jQuery
var $elems = $('a').Greenify(options);
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 :)
然而,这意味着我必须提供选项,如果我在没有选项的情况下执行构造函数,我得到的选项是未定义的。我勾选正确的答案对于我提出的问题是正确的。但是请记住,提供的答案要求您在打字稿构造函数中提供选项,我将了解如何使用默认选项,然后在构造函数中覆盖它们,但这是一个不同的问题:)
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
打字稿类
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
打字稿接口
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 :)
我希望这可以帮助其他和我有同样问题的人:)
采纳答案by jsonmurphy
You can create and referenceyour 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.
在编译时打字稿实际上会合并所有接口定义。
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
- Possibly more...
- 着色不能再是您的模块的名称,因为您必须在上面的接口定义中使用它
- 您可能必须创建一个将 .Greenify 作为静态方法的类
- 可能更多...
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;
}
回答by vorillaz
Creating jQuery plugins along with TypeScript can get a bit messy. I personally prefer keeping the jQuery plugin chaining syntax, mostly for consistency and maintainability .
与 TypeScript 一起创建 jQuery 插件可能会有点混乱。我个人更喜欢保留 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'
});
});