在AngularJS中观察/更新一组输入的正确方法

时间:2016-03-11 22:50:59

标签: jquery angularjs event-handling css-selectors smart-table

我在使用JQuery多年后,目前正在学习AngularJS。现在,我正在考虑实施智能表(http://lorenzofox3.github.io/smart-table-website/),并希望能够自动将搜索查询保存到cookie中,以便我可以在用户返回时重新加载它们。理想情况下,我想有一个通用的方法来做到这一点,所以我可以通过使用单个指令或DI重新使用代码。

在JQuery世界中,我会这样做:

HTML :由 st-search 定义的单个搜索条目,但我们可以使用 n - 这些都使用唯一ID'第

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

&#34;的onChange&#34; Javascript :收听所有字段更新,以便我可以调用我的存储服务(可能是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的做法。我试图按照这个建议来尝试做所有事情&#34;在Angular中没有JQuery("Thinking in AngularJS" if I have a jQuery background?),但我不确定如何最好地解决这个问题。你可以使用$ scope。$ watch一般会根据CSS选择器观察很多元素(我只能找到针对特定模型的例子)?最好是在每个输入或父 元素上使用装饰器吗?我真的不确定从哪里开始!

1 个答案:

答案 0 :(得分:0)

嗯,它不是一个漂亮的解决方案,但是通过将Angular与jQuery结合起来,它可以做我需要的东西!我决定在包含搜索字段的 tr 标记上使用属性/指令( st-search-cookie )。例如:

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

您可以选择在指令中定义 cookie-name collection-name 。否则,它使用所有可用搜索字段的md5哈希作为集合名称。这个想法是你有一个cookie,可以有许多不同的表的集合,而不是有很多的cookie(即每个表必须有一个)。

无论如何,这会自动找到默认的 st-search 输入框(输入[st-search] )以及带有*谓词&#39;的任何输入框。在制作自定义搜索指令时常用的属性(输入[谓词] )。

希望其他人会发现这有用,或者更好的是,改进它!

(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);