Есть ли чистый способ доступа к закрытым переменным внутри пространства имен - PullRequest
0 голосов
/ 16 марта 2011

Я использую сценарии пространства имен от https://github.com/smith/namespacedotjs для инкапсуляции моего специфичного для элемента управления javascript и jQuery-кода в моем приложении ASP.NET MVC.Без использования пространств имен методы с одинаковыми именами могут мешать друг другу и вызывать нежелательное поведение.

Вот мой текущий рабочий код :

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

Я посмотрел на документированный шаблон модуля Бена Черри , который я начал использовать;однако передача списка глобальных переменных, необходимых внутри кода модуля, каждый раз, когда вы создаете или обновляете модуль, кажется кошмаром обслуживания.

Решение для пространства имен выглядит синтаксически более чистым и было бы абсолютно идеальным, если бы я мог покончить с необходимостью полностью квалифицировать "частные" переменные.

У кого-нибудь есть хорошее решение этой дилеммы JavaScript?

Ответы [ 2 ]

1 голос
/ 20 марта 2011

Самый простой способ решить вашу проблему - это сохранить ссылку на ваш элемент управления в зависимости от того, какой метод вы собираетесь использовать. Фактически вы просто используете псевдоним класса.

        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 голосов
/ 20 марта 2011

Поскольку вы делаете selectedIds общедоступным членом своего пространства имен, в этом нет ничего «частного».

Если вы хотите истинной конфиденциальности, а также предоставляете методы на уровне одного уровня с доступом к переменнойопределите его внутри замыкания:

(function () {
    var selectedIds = [];

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

})();
...