我已经看过其他一些我认为可以提供帮助的帖子但却没有运气。当我静态指定要过滤的属性时,我有一个正常工作的过滤器。我正在构建一个角度组件,我不知道实际将哪些数据传递到组件中。例如,以下是一些示例数据:
this.customers = [
{ name: 'Jim', city: 'Minneapolis', state: 'MN', zip: 44332 },
{ name: 'Boe', city: 'Scottsdale', state: 'AZ', zip: 44332 },
{ name: 'Tom', city: 'S.F.', state: 'CA', zip: 11223 },
{ name: 'Joe', city: 'Dallas', state: 'TX', zip: 34543 },
{ name: 'Jon', city: 'L.A.', state: 'CA', zip: 56433 }
];
我的静态过滤器效果很好:
public filterTextChangeLocal($event: ng.IAngularEvent) {
if (this.itemDisplayProperty = "name") {
this.filteredItems = this.$filter("filter")(this.items, {name: this.ngModelValue});
} else if (this.itemDisplayProperty = "city") {
this.filteredItems = this.$filter("filter")(this.items, {city: this.ngModelValue});
} else if (this.itemDisplayProperty = "state") {
this.filteredItems = this.$filter("filter")(this.items, {state: this.ngModelValue});
} else if (this.itemDisplayProperty === "zip") {
this.filteredItems = this.$filter("filter")(this.items, {zip: this.ngModelValue});
}
}
问题是组件的用户可能传递任何类型的数据,其属性可能完全不同,因此我需要能够解释指定任何属性的内容。我有一个名为" itemDisplayProperty"的隔离范围属性。允许用户指定他们想要在下拉列表中显示的数据中的哪个属性,这是我需要过滤的属性。他们可以说," item-display-property ="地址&#34 ;,地址属性中的数据将显示在下拉列表中。我尝试了这个,但并没有像多个人那样工作,而且#34;不允许使用单词:
this.filteredItems = this.$filter("filter")(this.items, {
this.itemDisplayProperty : this.ngModelValue
});
这是我的输入和下拉参考:
<input type="text" class="form-control"
ng-change="ctrl.filterTextChangeLocal($event)"
ng-model="ctrl.ngModelValue"
ng-click="ctrl.openDropdown($event)" />
<ul class="dropdown-menu list-group" ng-if="!ctrl.ngDisabled">
<li class="list-group-item"
ng-repeat="row in ctrl.filteredItems"
ng-mousedown="ctrl.onSelectedLocal(row, $event)">
{{row[ctrl.itemDisplayProperty]}}
</li>
</ul>
答案 0 :(得分:3)
为了重构filterTextChangeLocal
内的静态过滤器,您需要做的就是使用动态密钥构建$filter
表达式。
这可以通过使用所谓的bracket notation:
来实现var obj = {};
obj[myKey] = value;
重构的filterTextChangeLocal
看起来像这样:
public filterTextChangeLocal($event: ng.IAngularEvent) {
var filterExpression = {};
filterExpression[this.itemDisplayProperty] = this.ngModelValue;
this.filteredItems = this.$filter("filter")(this.items, filterExpression);
}
答案 1 :(得分:1)
我用这种方式解决了我自己的问题,似乎是一种在对象中使用变量的新ES6方式。明确的答案也会起作用:
this.filteredItems = this.$filter("filter")(this.items, {[this.itemDisplayProperty] : this.ngModelValue});
答案 2 :(得分:0)
好的,没错,使用ES6你可以使用计算比例。
使用ES5,您可以创建一个这样的过滤器对象(控制器中带有var self=this;
):
var filterObj = {};
filterObj[self.itemDisplayProperty] = self.ngModelValue;
self.filteredItems = $filter("filter")(self.items, filterObj);
请查看下面的演示或此jsfiddle。
只记下您的变量名称。避免在您的名字中使用ng
前缀(例如代码中的ngDisabled
)。因为此变量与AngularJs无关,而另一个名称将使您的代码更具可读性。像showDrop
这样的东西会更好。
angular.module('demoApp', [])
.controller('mainController', MainController)
.directive('dynFilter', DynFilterDirective);
function DynFilterDirective($filter) {
return {
restrict: 'E',
controllerAs: 'ctrl',
templateUrl: 'components/dynFilterTempl.html',
bindToController: {
items: '=',
itemDisplayProperty: '='
},
scope: {},
controller: function() {
var self = this;
self.filterTextChangeLocal = function($event) {
var filterObj = {};
filterObj[self.itemDisplayProperty] = self.ngModelValue;
console.log(filterObj);
self.filteredItems = $filter("filter")(self.items, filterObj);
};
}
}
}
function MainController($filter) {
var vm = this;
vm.items = [
{ name: 'Jim', city: 'Minneapolis', state: 'MN', zip: 44332 },
{ name: 'Boe', city: 'Scottsdale', state: 'AZ', zip: 44332 },
{ name: 'Tom', city: 'S.F.', state: 'CA', zip: 11223 },
{ name: 'Joe', city: 'Dallas', state: 'TX', zip: 34543 },
{ name: 'Jon', city: 'L.A.', state: 'CA', zip: 56433 },
];
vm.keys = Object.keys(vm.items[0]);
vm.curProp = vm.keys[0];
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.4/angular.js"></script>
<div ng-app="demoApp" ng-controller="mainController as mainCtrl">
{{Object.keys(mainCtrl.items[0])}}
Choose your filter: <select ng-options="prop for prop in mainCtrl.keys" ng-model="mainCtrl.curProp"></select>
<dyn-filter item-display-property="mainCtrl.curProp" items="mainCtrl.items"></dyn-filter>
<script type="text/ng-template" id="components/dynFilterTempl.html">
<input type="text" class="form-control" ng-change="ctrl.filterTextChangeLocal($event)"
ng-model="ctrl.ngModelValue" ng-focus="ctrl.showDrop = true" ng-blur="ctrl.showDrop = false" />
<ul class="dropdown-menu list-group" ng-show="ctrl.showDrop">
<li class="list-group-item" ng-repeat="row in ctrl.filteredItems"
ng-mousedown="ctrl.onSelectedLocal(row, $event)">
{{row[ctrl.itemDisplayProperty]}}
</li>
</ul>
</script>
</div>
&#13;