Правильный способ просмотра / обновления группы входов в AngularJS

В настоящее время я работаю над изучением AngularJS после нескольких лет работы с JQuery. Прямо сейчас я смотрю на реализацию смарт-таблиц ( http://lorenzofox3.github.io/smart-table-website/) и хотел бы иметь возможность автоматически сохранять поисковые запросы в cookie, чтобы я мог их перезагрузить когда пользователь вернется. В идеале я хотел бы иметь общий способ сделать это, чтобы я мог повторно использовать код, используя одну директиву или DI.

В мире JQuery я бы сделал это:

HTML: одиночная поисковая запись, определенная st-search, но мы можем иметь n-ное число из них с уникальными идентификаторами.

<tr>
    <th><input st-search="id" class="form-control" placeholder="Search by ID" type="number"/></th>
</tr>

Javascript "onChange": слушайте все обновления полей, чтобы вместо предупреждений я мог вызвать свою службу хранения (возможно, cookie), чтобы сохранить обновленный параметр поиска для этой таблицы.

$('input[st-search]').on('change', function(event){
    var target = $(event.target);
    alert(target.attr('st-search')+'='+target.val());
});

Инициализация Javascript: это будет принимать cookieData и применять его ко всем соответствующим полям поиска.

$.each(cookieData, function(index, row) {
    $('input[st-search="'+row.stSearch+'"]').val(row.value);
});

Прямо сейчас я зацикливаюсь на том, что делает Angular. Я пытаюсь последовать предложению, чтобы попытаться сделать "все" в Angular без JQuery ( "Мышление в AngularJS", если у меня есть опыт работы с jQuery?), Но я не уверен, как лучше всего подойти к этому. Можете ли вы использовать $scope.$ Watch для общего просмотра множества элементов на основе селектора CSS (я могу найти только примеры, чтобы сделать это для конкретной модели)? Будет ли это лучше всего сделать с декоратором на каждом входе или родительском элемент? Я действительно не уверен, куда идти отсюда!

1 ответ

Решение

Ну, это не очень хорошее решение, но оно делает то, что мне нужно, комбинируя Angular с jQuery! Я решил использовать атрибут / директиву (st-search-cookie) для тега tr, который содержит поля поиска. Например:

<tr st-search-cookie>
    <th><input st-search="id" class="form-control" placeholder="Search by ID" type="number"/></th>
</tr>

Вы можете опционально определить имя cookie и имя коллекции в директиве. В противном случае он использует хэш md5 всех доступных полей поиска в качестве имени коллекции. Идея заключается в том, что у вас есть один файл cookie, который может иметь коллекции для множества разных таблиц, а не множество файлов cookie (т. Е. Иметь один файл для каждой таблицы).

В любом случае, он автоматически находит стандартные поля ввода st-search (input [st-search]), а также любые с атрибутом * предиката (input [предикат]), которые обычно используются при создании пользовательских директив поиска.

Надеюсь, кто-то найдет это полезным или, что еще лучше, улучшит его!

(function(angular) {
    angular.module("stSearchCookie", ['ngCookies', 'angular-md5']).directive('stSearchCookie', function ($cookies, md5, $log) {
        return {
            restrict: 'A',
            scope: {
                'cookieName': '@',
                'collectionName': '@'
            },
            transclude: false,
            link: {
                post: function (scope, elem, attrs, controller) {
                    // Set Defaults for scope
                    if (angular.isUndefined(scope.cookieName)) {
                        scope.cookieName = 'stSearchParams';
                        $log.log('cookie-name not defined so defaulting to "' + scope.cookieName + '"');
                    }
                    if (angular.isUndefined(scope.collectionName)) {
                        var fields = 'fieldNames=';
                        $.each(elem.find('input[st-search]'), function(i, e) {
                            fields = fields + $(e).attr('st-search') + ';';
                        });
                        $.each(elem.find('input[predicate]'), function (i, e) {
                            fields = fields + $(e).attr('predicate') + ';';
                        });
                        scope.collectionName = md5.createHash(fields);
                        $log.log('collection-name not defined so defaulting to "' + scope.collectionName + '"');
                    }

                    // Set defaults in cookie
                    var defaults = {};
                    $.each(elem.find('input[st-search]'), function(i, e) {
                        defaults[$(e).attr('st-search')] = '';
                    });
                    $.each(elem.find('input[predicate]'), function (i, e) {
                        defaults[$(e).attr('predicate')] = '';
                    });
                    var cookieData = $cookies.getObject(scope.cookieName);
                    if (angular.isObject(cookieData)) {
                        if (cookieData.hasOwnProperty(scope.collectionName))
                            cookieData[scope.collectionName] = angular.extend(defaults, cookieData[scope.collectionName]);
                        else
                            cookieData[scope.collectionName] = defaults;
                    } else {
                        cookieData = {};
                        cookieData[scope.collectionName] = defaults;
                    }
                    $cookies.putObject(scope.cookieName, cookieData);

                    // Populate from cookie
                    $.each(Object.keys(cookieData[scope.collectionName]), function (index, key) {
                        $('input[st-search="' + key + '"]').val(cookieData[scope.collectionName][key]).trigger('change').trigger('blur');
                    });
                    $.each(Object.keys(cookieData[scope.collectionName]), function (index, key) {
                        $('input[predicate="' + key + '"]').val(cookieData[scope.collectionName][key]).trigger('change').trigger('blur');
                    });

                    // Add events to update cookie on changes
                    elem.find('input[st-search]').on('change blur', function(event) {
                        var target = $(event.target);
                        var cookieData = $cookies.getObject(scope.cookieName);
                        cookieData[scope.collectionName][target.attr('st-search')] = target.val();
                        $cookies.putObject(scope.cookieName, cookieData);
                    });
                    elem.find('input[predicate]').on('change blur', function (event) {
                        var target = $(event.target);
                        var cookieData = $cookies.getObject(scope.cookieName);
                        cookieData[scope.collectionName][target.attr('predicate')] = target.val();
                        $cookies.putObject(scope.cookieName, cookieData);
                    });
                }
            }
        };
    });
})(angular);
Другие вопросы по тегам