使用 AngularJS 清除绑定的 SmartTable 文本框

Clear bound SmartTable textbox with AngularJS

我在 Angular 1.2.x 应用程序中使用 SmartTable。具体来说,我遵循的是谓词列表驱动搜索过程的模式。项目站点 here 上给出了一个具体示例。

从示例中可以看出,当您 select 一个谓词并执行搜索,然后 select 列表中的另一个谓词时,文本框仍然包含之前的搜索条件。

我是 AngularJS 的新手,我正在尝试以 AngularJS 的方式清除谓词 select 框的更改事件的搜索结果。我的第一个想法是将任何类型的 DOM 操作推到指令后面。所以我创建了一个用于重置搜索条件的调用 "tndResetSearch" 。我在 jade 中的语法看起来很乱......如果有更好的方法来组织它,我欢迎提出建议 ;) :

select.form-control.tnd-reset-search(name="selectedPredicate", type="text" ng-model="selectedPredicate",
  ng-options="predicate.PredicateId as predicate.PredicateName for predicate in predicates",
  itemdata="predicate", options="#serviceLogSearchBox", resetsearch="resetSearch()")

resetsearch="resetSearch()" 绑定到我的指令的隔离范围 属性。

它的实现在控制器中,它只是从 $scope 中清除模型并重新填充 smart-table 用来填充视图的集合:

$scope.resetSearch = function() {
  delete $scope.searchQuery;
  $scope.initCollection();
}

$scope.initCollection = function() {
  $scope.serviceLogCollection = '';
  $scope.serviceLogCollection = [].concat($scope.originalServiceLogCollection);
};

这执行得很好,但每次我更改 select 框中的谓词时,以前的搜索条件似乎被缓存并附加到当前搜索条件。所以我最终得到了之前搜索的一个子集。我不确定缓存发生在哪里。 $scope 中必须有 SmartTable 搜索指令在下一次搜索之前查看的内容。接下来我将不得不查看 SmartTable 看看我是否可以找到它,除非我在我的方法中做错了一些事情。

上面 select 框中的 options="#serviceLogSearchBox" 是我的另一个尝试,试图获取对关联搜索框的引用并手动清除它,但根本没有效果。

这是我对指令的第一次尝试:

angular.module('app').directive('tndResetSearch', [function() {
    return {
        restrict: 'CA',
        replace: false,
        transclude: false,
        scope: {
            index: '=index',
            predicate: '=itemdata',
            resetSearch: '&resetsearch'
        },
        link: function(scope, elem, attrs) {

            var maxNukes=100, currentNuke=0, triggerKeyDown, nukeSearch;

            triggerKeyDown = function (element, keyCode) {
              var e = angular.element.Event('keydown');
              e.which = keyCode;
              element.trigger(e);
            };

            nukeSearch = function() {
                // Trigger keydown event for bound element that uses the stSearch directive???
                // This never actually does anything, It just loops forever.
                //
                // var target = angular.element(attrs.options);
                // while (target.val().length > 0 && currentNuke < maxNukes) {
                //    triggerKeyDown(target, 8); //backspace=8
                //    currentNuke++;
                //}
                // Call referenced function on isolate scope
                scope.resetSearch();
            };

            // Modify the DOM the first time the view renders with the first item selected
            if (parseInt(scope.index)===0) {
                nukeSearch();
            }

            elem.bind('change', function (evt) {
                nukeSearch();
            });

        }
    }
}]);

有谁知道为什么我会看到我提到的行为,我是不是用错了方法?如果是这样,使用 Angular 1.2.x 和 SmartTable 的最佳方法是什么?

好吧,我将上面的 tndResetSearch 指令简化为:

angular.module('app').directive('tndResetSearch', ['$parse', function($parse) {
    return {
        require: '^stTable',
        restrict: 'CA',
        link: function(scope, elem, attrs, ctrl) {

            var tableCtrl = ctrl,
                fn = $parse(attrs['resetSearch']);

            nukeSearch = function(evt) {
                scope.$apply(function() {
                    fn(scope, {
                        $event: evt
                    })
                });
            };

            elem.bind('change', function (evt) {
                nukeSearch(evt);
            });

        }
    }
}]);

...然后不要这样做:

$scope.resetSearch = function() {
  delete $scope.searchQuery;
  $scope.initCollection();
}

我这样做了并且有效:

$scope.resetSearch = function(evt) {
  $scope.initCollection();
  $scope.searchQuery = ' ';
}

searchQuery就是我搜索输入框的ng-model。似乎它必须是空字符串、null 或 undefined 的任何内容。否则,stSearch 指令看不到变化并假定先前的搜索值仍然存在。

值得一提的是我的搜索文本框(玉质):

input.form-control(id="serviceLogSearchBox", 
  st-search="{{selectedPredicate}}", placeholder="Search", 
  type="search", ng-model="searchQuery")