I am using the Namespace scripts from https://github.com/smith/namespacedotjs to encapsulate my control-specific javascript and jQuery code in my ASP.NET MVC application. Without using namespaces, methods of the same name can interfere with each other and cause undesired behavior.
Here is my current working code:
<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.SelectDrawing开发者_开发百科NumbersControl.selectedIds, function(item, index) {
return item != $check.val();
});
}
});
}
}
});
</script>
However, in the code sample above, notice I am using a variable "selectedIds" which is an array of strings. Since this variable is declared as part of my namespace I am now forced to reference it, from other methods inside the same namespace, by it's fully-qualified path.
Ideally, I would prefer to write something like this:
<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>
My existing code sample #1 above feels pretty cumbersome - I am used to writing C# and referencing objects from the same namespace without fully qualifying them (i.e. code sample #2).
I have looked at Ben Cherry's documented module pattern, which I started to use; however, passing in the list of all globals needed inside the module code every time you create or update a module seems like a maintenance nightmare.
The namespace solution seems syntactically cleaner and would be absolutely perfect if I could do away with the need to fully qualify "private" variables.
Does anyone have a good solution to this JavaScript dilemma?
The easiest way I can think to resolve your problem would be to keep a reference to your control within whichever method you intend to use. Effectively you're just aliasing the classname.
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();
});
}
});
}
Since you're making selectedIds
a public member of your namespace, there's nothing "private" about it.
If you want true privacy, while also giving methods at a sibling level access to the variable, define it inside a closure:
(function () {
var selectedIds = [];
Namespace('MyCompany.MyApp.ReviseDrawingNumber.AddSheetNumber', {
SelectDrawingNumbersControl: {
setSelectedIds: function() {
// use selectedIds directly
...
})();
精彩评论