2011-03-30 85 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:將您的小部件縮進另一個級別。