有没有一种干净的方法来访问命名空间内的私有变量
我正在使用 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)。
我查看了 Ben Cherry 的记录的模块模式,其中我开始使用;然而,每次创建或更新模块时,在模块代码中传递所需的所有全局变量的列表似乎是维护的噩梦。
命名空间解决方案在语法上看起来更干净,如果我可以消除完全限定“私有”变量的需要,那将是绝对完美的。
有没有人有一个好的解决方案来解决这个 JavaScript 困境?
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.SelectDrawingNumbersControl.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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为解决您的问题的最简单方法是在您打算使用的任何方法中保留对控件的引用。实际上,您只是为类名添加别名。
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.
由于您要将
selectedIds
设为命名空间的公共成员,因此它没有任何“私有”内容。如果您想要真正的隐私,同时还为同级级别的方法提供对变量的访问权限,请将其定义在闭包内:
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: