开发者

Is there a clean way to access private variables inside a Namespace

开发者 https://www.devze.com 2023-02-17 19:29 出处:网络
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, met

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
                ...

})();
0

精彩评论

暂无评论...
验证码 换一张
取 消