2011-03-16 40 views
0

我使用https://github.com/smith/namespacedotjs的命名空間腳本來封裝我的ASP.NET MVC應用程序中特定於控件的javascript和jQuery代碼。如果不使用名稱空間,同名的方法可能會相互干擾並導致不良行爲。是否有乾淨的方式來訪問命名空間內的私有變量

這是我的當前工作碼

<script type="text/javascript"> 

Namespace('MyCompany.MyApp.ReviseDrawingNumber.AddSheetNumber', { 

     SelectDrawingNumbersControl: { 
      selectedIds: [], 

      setSelectedIds: function() { 
       // wire up checkboxes 
       $('#DrawingSheetNumbersGrid :checkbox').live('change', function(e) { 
        var $check = $(this); 
        console.log($check); 
        if ($check.is(':checked')) { 
         // add id to selectedIds 
         MyCompany.MyApp.ReviseDrawingNumber.AddSheetNumber.SelectDrawingNumbersControl.selectedIds.push($check.val()); 
        } 
        else { 
         // remove id from selectedIds 
         MyCompany.MyApp.ReviseDrawingNumber.AddSheetNumber.SelectDrawingNumbersControl.selectedIds = 
          $.grep(MyCompany.MyApp.ReviseDrawingNumber.AddSheetNumber.SelectDrawingNumbersControl.selectedIds, function(item, index) { 
          return item != $check.val(); 
         }); 
        } 
       }); 
      }  
     } 
    }); 

</script> 

然而,上面的代碼示例中,通知我使用的變量「selectedIds」,這是一個字符串數組。由於這個變量是作爲我的命名空間的一部分被聲明的,我現在不得不通過它的全限定路徑從同一命名空間內的其他方法引用它。

理想情況下,我寧願寫的是這樣的:

<script type="text/javascript"> 

Namespace('MyCompany.MyApp.ReviseDrawingNumber.AddSheetNumber', { 

     SelectDrawingNumbersControl: { 
      selectedIds: [], 

      setSelectedIds: function() { 
       // wire up checkboxes 
       $('#DrawingSheetNumbersGrid :checkbox').live('change', function(e) { 
        var $check = $(this); 
        console.log($check); 
        if ($check.is(':checked')) { 
         // add id to selectedIds 
         selectedIds.push($check.val()); 
        } 
        else { 
         // remove id from selectedIds 
         selectedIds = $.grep(selectedIds, function(item, index) { 
          return item != $check.val(); 
         }); 
        } 
       }); 
      }  
     } 
    }); 

</script> 

我現有的代碼示例#1上面感覺很繁瑣 - 我來寫C#和來自同一個命名空間中引用對象沒有完全限定他們(即代碼示例#2)。

我看過本櫻桃的documented module pattern,我開始使用;但是,每次創建或更新模塊時,都要在模塊代碼中傳遞需要的所有全局變量的列表,這看起來像是一個維護噩夢。

命名空間解決方案在語法上看起來更乾淨,如果我可以取消完全限定「私有」變量的需要,那將是絕對完美的。

有沒有人有這個JavaScript的困境很好的解決方案?

回答

1

我認爲解決您的問題的最簡單方法是在您打算使用的任何方法中保留對控件的引用。實際上,你只是別名類別。

 setSelectedIds: function() { 
      //keep a reference to SelectDrawingNumbersControl in case we need it 
      var that = this; 

      // wire up checkboxes 
      $('#DrawingSheetNumbersGrid :checkbox').live('change', function(e) { 
       var $check = $(this); 
       console.log($check); 
       if ($check.is(':checked')) { 
        // add id to selectedIds 
        that.selectedIds.push($check.val()); 
       } 
       else { 
        // remove id from selectedIds 
        that.selectedIds = 
         $.grep(that.selectedIds, function(item, index) { 
         return item != $check.val(); 
        }); 
       } 
      }); 
     } 
0

既然你讓你的selectedIds命名空間的公共成員,沒有什麼「私」了。

如果你想真正的隱私,同時在同級級別訪問變量給方法,它定義一個閉包:

(function() { 
    var selectedIds = []; 

    Namespace('MyCompany.MyApp.ReviseDrawingNumber.AddSheetNumber', { 
     SelectDrawingNumbersControl: { 
      setSelectedIds: function() { 
       // use selectedIds directly 
       ... 

})(); 
+0

這個局部變量的偉大工程,怎麼樣私人的功能呢? – Winger 2011-03-21 20:00:34

+0

完全相同的方式。您可以在'selectedIds'定義的同一位置定義私有函數。 – 2011-03-22 02:35:18

相關問題