2011-03-30 64 views
11

关于jQuery UI的小部件工厂的静态/类变量...如何声明在jQuery UI的小部件厂部件

什么是有一个被所有共享的静态变量/类级别变量的最佳方式实例?

例如在上面,如果staticVar是静态的,$('#parent')。staticTest('test');会提醒'已更改',但会提示'未更改'。

(此代码是的jsfiddle如果你想有一个剧本:http://jsfiddle.net/alzclarke/Sx8pJ/

我能想到自己的解决方案是丑陋的。

1)$( '主体')的数据(“sharedVariable ',myData) - 这似乎不是一个好习惯,如果某人或某事清除了数据主体,那么该怎么办2)将其存储在原型命名空间中,例如= $ .ui.staticTest.prototype.staticVar = myData; 这也是响铃警钟

回答

24

闭包是你的答案

(function($) { 

var staticVariable = ''; 

$.widget('ui.newWidget', { 
    options: { 

    }, 
    _init: function() { 
    } 

}); 

})(jQuery); 

staticVariable只会在刚刚定义,因为它是包裹在会立即叫匿名函数小部件的范围可用的(像你应该已经做了你的jQuery/jquery ui插件。

+1

这是一个很好的答案,非常简单,与其他答案不同,它允许静态变量真正是私有的。 – alzclarke 2012-05-24 17:36:30

+2

我可以问一个人如何从widget外部访问(设置)staticVariable吗?我需要一个可以为所有窗口小部件实例配置一次的选项。 – Marc 2012-11-03 16:10:58

+0

您可以创建一个函数来使其具有全局范围 – 2012-11-09 16:48:53

0

看起来好像对“这个”这个关键词有点误解。这里这个关键字将该变量作为实例特定的。尝试下面的代码。

$.widget("ui.staticTest", { 
    staticVar:'unchanged', 
    test: function(a){ 
     if(a){ 
      staticVar= a; 
     } 
     alert(JSON.stringify(staticVar)); 
    } 
}); 

$('#test').staticTest(); 
$('#parent').staticTest(); 

$('#test').staticTest('test','changed'); 
$('#parent').staticTest('test'); 
+0

@alzclarke,我试过了,我在两个调用中都发生了“变化”。我是否错过了什么? – 2011-04-01 06:30:42

+0

对不起,你是对的!实际上,代码是声明和分配一个全局变量不是类变量,如果我用行警告(staticVar)运行你的代码;最后,它也会提醒'changed'。同样,如果调用前的任何代码使用此变量名称,该值将丢失。 – alzclarke 2011-04-01 06:48:05

2

似乎小部件没有共享范围。任何。所以我要做的就是在jQuery UI对象本身上定义一个共享对象,就像你自己提出的那样。

注意:共享对象名称应该反映控件名称和名称空间。

$.ui.staticShared = { color: "#fff" }; 

$.widget("ui.static", { 
    color: function (o) 
    { 
     if (typeof o !== "undefined") $.ui.staticShared.color = o; 

     return $.ui.staticShared.color; 
    } 
}); 

这就像它在我眼中一样干净。当然,人们有压倒共享对象的风险,但如果发生这种情况,世界将不会分崩离析。

如果您想要某种故障安全/反馈,如果共享对象无效或已被覆盖,您可以检查_init事件上的对象结构。

$.widget("ui.static", { 
    _init: function() 
    { 
     if (typeof $.ui.staticShared === "undefined") 
     { 
      alert("$.ui.staticShared is required for this plug-in to run"); 
     } 
    }, 
}); 

_init事件在创建实例时触发。

+0

你好,好想法,但在这里你声明和分配一个全局变量不是一个类变量。如果我用行警告(_static)运行你的代码;最后,它还会提醒'酒吧'。同样,如果调用前的任何代码使用此变量名称,则该值将丢失 – alzclarke 2011-04-01 06:43:49

+0

@alzclarke:您说得对。 _Static被定义在窗口对象上。很好地发现:) – roosteronacid 2011-04-01 09:10:15

+0

更新了我的答案。 – roosteronacid 2011-04-01 09:27:06

0

//详细例子在widget范围

$.widget("ui.staticTest", { 
    //staticVar is an instance variable, regardless of what it is named as 
    staticVar: 'brownMamba', 

    _create: function() { 

    }, 

    //test the static variable 
    testStatic: function(a) { 
     if (a) { 
     //Here you're actually creating a new static variable called 
     //staticVar which is associated with the staticTest object as you assign 
     //value to it. 
      //Lemme show you what I mean with an example 
      //Here it alerts 'Undefined' as 'staticVar' does not exists 
      //don't confuse it with the staticVar: 'brownMamba' declared above, 
      //that one is an instance variable 
      alert("Type of $.ui.staticTest.staticVar before assignment: " + typeof $.ui.staticTest.staticVar); 

      $.ui.staticTest.staticVar = a; 
      //At this point it alerts the type of 'a', which in our case is 'string'    
      alert("Type of $.ui.staticTest.staticVar after assignment: " + typeof $.ui.staticTest.staticVar); 

      //value of instance variable at this point 
      alert("typeof this.staticVar: " + typeof this.staticVar); 
      alert("Value of this.staticVar: " + this.staticVar); 
      //value of global variable at this point 
      //'Undefined' as it does not exist 
      alert("Type of staticVar: " + typeof staticVar); //or window.staticVar 


     } else { 
      alert("value of staticVar in testStatic with no argument: " + $.ui.staticTest.staticVar); 
     } 
    }, 

    //test the instance variable 
    testInstance: function(a) { 
     if (a) { 
     //Here you're actually working with the instance variable declared above, 
     //with the value 'brownMamba' 
     //Lemme show you what I mean with an example 
     //Here it alerts 'string' as 'staticVar' exists and is assigned a string 
      alert("typeof this.staticVar is " + typeof this.staticVar + " and its 
value is " + this.staticVar); 

      this.staticVar = a; 
      alert("typeof this.staticVar after assignment is " + typeof this.staticVar); 
      alert("Value of this.staticVar after assignment is " + this.staticVar); 
     } else { 
      alert("value of this.staticVar in testInstance with no argument: " + this.staticVar); 
     } 
    }, 

    //test the Global variable 
    testGlobal: function(a) { 
     if (a) { 
     /*Here you're actually creating a global variable called staticVar*/ 
      //Lemme show you what I mean with an example 
      //Here it alerts 'Undefined' as 'staticVar' does not exists 
      alert("Type of staticVar before assignment: " + typeof staticVar); 

      staticVar = a; //creating a global variable, which will be declared 
in window scope, i.e. window.staticVar 
      //At this point it alerts the type of a, which in our case is a 'string'    
      alert("Type staticVar after assignment: " + typeof staticVar); 
      alert("Value of staticVar after assignment: " + staticVar) 
     } else { 
      alert("value of staticVar in testGlobal with no argument: " + staticVar); 
     } 
    } 
}); 

//instantiating widget 
$('#test').staticTest(); 
//instantiating widget 
$('#parent').staticTest(); 

$('#test').staticTest('testStatic', 'changed'); 
//value will be sustained as its associated to the object 
$('#parent').staticTest('testStatic'); 

$('#test').staticTest('testInstance', 'bluemamba'); 
//here the value doesn't change as its an instance variable and its value is not altered 
$('#parent').staticTest('testInstance'); 

$('#test').staticTest('testGlobal', 'bluemamba'); 
//here the value is still sustained as the global is created in the previous call 
$('#parent').staticTest('testGlobal'); 

http://jsfiddle.net/hiteshubharani/z5k4E/6/

+0

你好,公鸡的解决方案基本上是使用一个全局变量,但具有托管命名空间。因此你并不需要在构造函数中引用它。我已经修改你的解决方案 – alzclarke 2011-05-04 13:09:41

+0

alzclarke,我会感激你添加你自己的答案,而不是完全修改我的帖子。 – brownmamba 2011-05-14 02:42:10

+0

@brownmamba够公平的,我已经恢复了我的编辑并添加了一个新的答案,soz,并不意味着冒犯了! – alzclarke 2011-05-15 08:43:43

1

解释静态,实例和全局变量实际上,如果你的变量是一个对象,它是自动静态... HMMMMMMMM非常有帮助! (不)...特别是考虑到包含原语的变量显示相反的行为。必须与旧的“指针不是对象”成语有关。

ANYWHO ...

IF您的变量包含对象{}下面将正确的答案,否则,请参阅其他的答案:

静态示例:

$.widget("ui.staticTest", { 
    staticVar:{val:'unchanged'}, 
    _create: function(){ 
    }, 
    test: function(a){ 
     if(a){ 
      this.staticVar.val= a; 
     } 
     alert(JSON.stringify(this.staticVar.val)); 
    } 
}); 


$('#test').staticTest(); 
$('#parent').staticTest(); 

$('#test').staticTest('test','changed'); 
$('#parent').staticTest('test'); 

http://jsfiddle.net/alzclarke/Sx8pJ/9/

NON静态示例:

$.widget("ui.staticTest", { 
    _create: function(){ 
     this.staticVar={val:'unchanged'}; 
    }, 
    test: function(a){ 
     if(a){ 
      this.staticVar.val= a; 
     } 
     alert(JSON.stringify(this.staticVar.val)); 
    } 
}); 


$('#test').staticTest(); 
$('#parent').staticTest(); 

$('#test').staticTest('test','changed'); 
$('#parent').staticTest('test'); 

http://jsfiddle.net/alzclarke/Sx8pJ/10/

+0

如果您在复杂的实例变量之后记下此示例 - 基本类型对于每个窗口小部件的实例都是唯一的,但对象类型在实例之间共享。如果您需要实例对象类型,请将其作为其中的一部分。选项,它始终是特定于实例的 – 2011-06-20 11:07:37

+0

是 - 除非这违反了封装,在这种情况下,您的其他选项是在_create或_init方法中声明对象变量。 – alzclarke 2011-07-20 09:18:00

+1

静态变量通常是常量,按照约定,它将具有ALL_CAPS名称。具有讽刺意味的是,我在这个页面上看到的唯一ALL_CAPS就是在这个令人吃惊的答案中。 – 2016-09-22 18:14:22

0

简单公鸡soludion的执行力度:在

你的jsfiddle的
$.widget("ui.staticTest", (function() { 

    staticVar:'unchanged'; 

    return { 
     test: function(a){ 
      if(a){ 
       staticVar= a; 
      } 
      alert(JSON.stringify(staticVar)); 
     } 
    }; 
}())); 

叉:http://jsfiddle.net/pettys/RwKdZ/

临:什么神奇

$.widget("ui.staticTest", { 
test: function(a){ 
    if(a){ 
     $.ui.staticTest.staticVar= a; 
    } 
    alert(JSON.stringify($.ui.staticTest.staticVar)); 
} 
}); 
$.ui.staticTest.staticVar = 'unchanged'; 


$('#test').staticTest(); 
$('#parent').staticTest(); 
$('#test').staticTest('test'); 
$('#test').staticTest('test','changed'); 
$('#parent').staticTest('test'); 
0

你可以使用一般的JS封装模式继续,而不是搞乱jQuery空间。 Con:将您的小部件缩进另一个级别。