Angularjs 角度:进一步的动态过滤问题

Angularjs 角度:进一步的动态过滤问题,angularjs,Angularjs,我正在努力让这些动态过滤器工作,我想它就快到了。看起来模型没有被传递回watch函数。我本以为它至少能与第一组过滤器一起工作,但事实并非如此 我试图实现的是,当用户从选择列表中选择一个选项并在输入框中设置一个值时,数据将被过滤。用户可以通过单击“添加字段”按钮选择添加另一组过滤器。如果用户完成了第二组过滤器,则会进一步过滤数据 这就是我到目前为止得到的。如果只有一个过滤器显示,那么它不应该工作吗 这是创建用户定义过滤器的代码 <div data-ng-repeat="filter in f

我正在努力让这些动态过滤器工作,我想它就快到了。看起来模型没有被传递回watch函数。我本以为它至少能与第一组过滤器一起工作,但事实并非如此

我试图实现的是,当用户从选择列表中选择一个选项并在输入框中设置一个值时,数据将被过滤。用户可以通过单击“添加字段”按钮选择添加另一组过滤器。如果用户完成了第二组过滤器,则会进一步过滤数据

这就是我到目前为止得到的。如果只有一个过滤器显示,那么它不应该工作吗

这是创建用户定义过滤器的代码

<div data-ng-repeat="filter in filters">
  <select ng-model="filter.id">
    <option value="age">Age</option>
    <option value="customerId">CustomerID</option>
    <option value="productId">ProductID</option>
    <option value="name">Name</option>
  </select>
  <input type="text" ng-model="data.search[filter.id]">
  <button class="remove" ng-show="$last" ng-click="removeFilter()">-</button>

年龄
客户编号
产品ID
名称
-
添加字段

我想我就快到了,对层次范围有了更好的理解。我已经提到了一些教程和例子,但我还不太清楚。我认为我的问题在于我没有正确地传达模型。还是有点迷茫。任何进一步的提示/建议都很好。我想知道是否应该将指令中控制器的一些代码移到
resultsCtrl
控制器中。真的不确定

这让我想到在我的模板中使用
filter.id
ng repeat

这很有帮助

我现在有进展了。显示它正在工作,我最不想做的事情是当你删除一个过滤器时,它会自动更新搜索对象以删除相关的过滤器


有什么建议吗?

你打破了“在
ng模型中始终有一个点”的黄金法则

为什么??因为对象具有继承性,而基本体不具有继承性

ng-model="filterType"
正在由
ng repeat
创建的子作用域内定义。因为它是一个原语,所以控制器中的父作用域无法看到它。但是,如果它是在父级可用的对象的属性,则该引用将在父级和子级之间共享

一旦你修复了这个bug,你会遇到一个bug,其中
scope.search
也不是一个对象,所以你的$watch函数也会抛出一个异常。在主控制器中,可以设置:

$scope.search ={};

读一些关于层次作用域如何在角度上工作的书。在网络搜索和角度文档中可以找到大量内容

您正在打破“在
ng模型中始终有一个点”的黄金法则

为什么??因为对象具有继承性,而基本体不具有继承性

ng-model="filterType"
正在由
ng repeat
创建的子作用域内定义。因为它是一个原语,所以控制器中的父作用域无法看到它。但是,如果它是在父级可用的对象的属性,则该引用将在父级和子级之间共享

一旦你修复了这个bug,你会遇到一个bug,其中
scope.search
也不是一个对象,所以你的$watch函数也会抛出一个异常。在主控制器中,可以设置:

$scope.search ={};

读一些关于层次作用域如何在角度上工作的书。在网络搜索和角度文档中可以找到很多内容

我最终解决了这个问题:)

指令:

angular.module('dynamicFiltersDirective', [])
.directive('dynamicFilters', function() {
  return {
    restrict: 'AE',  
    scope: {
             filtersArray: '=',
             searchObject: '='
    },

    link: function(scope) {

      scope.addFilter = function() {
        var newItemNo = scope.filtersArray.length+1;
        scope.filtersArray.push({'id':'filter'+newItemNo});
      };

      scope.removeFilter = function(option) {
        var lastItem = scope.filtersArray.length-1;
        scope.filtersArray.splice(lastItem);
        delete scope.searchObject[option];
      };    

      scope.updateFilters = function (model) {
        scope.searchObject[model];
      }

    },
    templateUrl: 'filtertemplate.html'
  }
});
控制器:

angular.module('app', ['dynamicFiltersDirective']).controller('resultsCtrl', function($scope){

$scope.filters = [{id: 'filter1'}];
$scope.search = {};

    $scope.persons = [{
      name: 'Jim',
        age: 21,
      customerId: 1,
      productId: 4
  },{
      name: 'Frank',
        age: 20,
      customerId: 2,
      productId: 4
  },{
      name: 'Bob',
        age: 20,
      customerId: 3,
      productId: 5
  },{
      name: 'Bill',
        age: 20,
      customerId: 3,
      productId: 5
  }];
});
模板:

<div data-ng-repeat="filter in filtersArray">
  <select ng-model="filter.id">
    <option value="age">Age</option>
    <option value="customerId">CustomerID</option>
    <option value="productId">ProductID</option>
    <option value="name">Name</option>
  </select>
  <input type="text" ng-model="searchObject[filter.id]" ng-change="updateFilters(searchObject[filter.id])">
  <button class="remove" ng-show="$last" ng-click="removeFilter(filter.id)">-</button>
</div>
<button class="addfields" ng-click="addFilter()">Add fields</button>

<div id="filtersDisplay">
  {{ filters }}
</div>   

年龄
客户编号
产品ID
名称
-
添加字段
{{filters}}
index.html

<div ng-controller="resultsCtrl">
 <dynamic-filters filters-array="filters" search-object="search">    </dynamic-filters>
 <div ng-repeat="person in persons | filter: search">
   {{person.name}}
</div>

{{person.name}


这是我的

我最终解决了这个问题:)

指令:

angular.module('dynamicFiltersDirective', [])
.directive('dynamicFilters', function() {
  return {
    restrict: 'AE',  
    scope: {
             filtersArray: '=',
             searchObject: '='
    },

    link: function(scope) {

      scope.addFilter = function() {
        var newItemNo = scope.filtersArray.length+1;
        scope.filtersArray.push({'id':'filter'+newItemNo});
      };

      scope.removeFilter = function(option) {
        var lastItem = scope.filtersArray.length-1;
        scope.filtersArray.splice(lastItem);
        delete scope.searchObject[option];
      };    

      scope.updateFilters = function (model) {
        scope.searchObject[model];
      }

    },
    templateUrl: 'filtertemplate.html'
  }
});
控制器:

angular.module('app', ['dynamicFiltersDirective']).controller('resultsCtrl', function($scope){

$scope.filters = [{id: 'filter1'}];
$scope.search = {};

    $scope.persons = [{
      name: 'Jim',
        age: 21,
      customerId: 1,
      productId: 4
  },{
      name: 'Frank',
        age: 20,
      customerId: 2,
      productId: 4
  },{
      name: 'Bob',
        age: 20,
      customerId: 3,
      productId: 5
  },{
      name: 'Bill',
        age: 20,
      customerId: 3,
      productId: 5
  }];
});
模板:

<div data-ng-repeat="filter in filtersArray">
  <select ng-model="filter.id">
    <option value="age">Age</option>
    <option value="customerId">CustomerID</option>
    <option value="productId">ProductID</option>
    <option value="name">Name</option>
  </select>
  <input type="text" ng-model="searchObject[filter.id]" ng-change="updateFilters(searchObject[filter.id])">
  <button class="remove" ng-show="$last" ng-click="removeFilter(filter.id)">-</button>
</div>
<button class="addfields" ng-click="addFilter()">Add fields</button>

<div id="filtersDisplay">
  {{ filters }}
</div>   

年龄
客户编号
产品ID
名称
-
添加字段
{{filters}}
index.html

<div ng-controller="resultsCtrl">
 <dynamic-filters filters-array="filters" search-object="search">    </dynamic-filters>
 <div ng-repeat="person in persons | filter: search">
   {{person.name}}
</div>

{{person.name}


这是我的

我做了一些研究,我明白为什么我需要模型中的点。我现在使用filter.id作为ng repeat中的模式。我的手表没有任何变化,我正在查看filter.id。你有没有可能再看一眼,再给我一个指针?:)
filter.id
不是范围变量,它是
filters
数组中每个筛选器对象的属性。我建议您使用事件来实现这一点,比如
ng change
我做了一些研究,我明白为什么我需要模型中的点。我现在使用filter.id作为ng repeat中的模式。我的手表没有任何变化,我正在查看filter.id。你有没有可能再看一眼,再给我一个指针?:)
filter.id
不是范围变量,它是
filters
数组中每个筛选器对象的属性。我建议您对此使用事件,如
ng change