Angularjs下拉列表和自定义筛选器存在问题

Angularjs下拉列表和自定义筛选器存在问题,angularjs,angularjs-ng-repeat,angularjs-filter,Angularjs,Angularjs Ng Repeat,Angularjs Filter,我在使用填充了ng repeat选项值的下拉列表时遇到了问题,甚至在使用ng选项时也遇到了问题 基本上我是从数据库中提取子公司的列表。然后我有一个下拉列表来选择一家公司,这反过来应该用所选公司的子公司填充子公司下拉列表。由于许多子公司属于同一家公司,如果我尝试在ng repeat中提取公司名称,我会多次得到同一家公司。因此,我创建了一个自定义过滤器,它只过滤列出的每个公司的companyName和companyID一次 理论上,当我改变公司下拉列表的价值时,正确的子公司就会被列出。但是,公司框中

我在使用填充了ng repeat选项值的下拉列表时遇到了问题,甚至在使用ng选项时也遇到了问题

基本上我是从数据库中提取子公司的列表。然后我有一个下拉列表来选择一家公司,这反过来应该用所选公司的子公司填充子公司下拉列表。由于许多子公司属于同一家公司,如果我尝试在ng repeat中提取公司名称,我会多次得到同一家公司。因此,我创建了一个自定义过滤器,它只过滤列出的每个公司的companyName和companyID一次

理论上,当我改变公司下拉列表的价值时,正确的子公司就会被列出。但是,公司框中显示的值将固定在列出的第一个选项上,并且不会更改。如果删除自定义过滤器并允许其列出所有重复名称,则该框将正确显示

我的第一个想法是进行一个单独的HTTP调用,该调用只从我的companys表中获取companys,但我认为我希望将HTTP调用限制在尽可能少的范围内。另外,我似乎应该能够做到这一点

当我使用我的过滤器时,我没有掌握什么概念阻止它正确显示,我应该怎么做来修复它? 谢谢

HTML:

过滤器:

.filter("uniqueCompanies", function() {
            return function(data, propertyName) {
                if (angular.isArray(data) && angular.isString(propertyName)) {
                    var results = [];
                    var keys = {};
                    for (var i = 0; i < data.length; i++) {
                        var val = data[i][propertyName];
                        var val2 = data[i]['companyID'];
                        if (angular.isUndefined(keys[val])) {
                            keys[val] = true;
                            results.push({'name':val, 'id':val2});
                        }
                    }
                    return results;
                } else {
                    return data;
                }
            };
        });

我可能不完全理解您在这里的问题,但看起来您可以在获得数据时过滤数据。比如

function getCompanies(){
  $http.get("get.php?table=getcompanies").success(function(data) {
    $scope.companies = data.reduce(function (prev, cur) {
      // some code for skipping duplicates goes here                              
    }, []);
  });
}

Array.reduce可能不是获得没有重复项的新数组的最佳方法,但无论如何,这是一般的想法。

您正在过滤器中创建具有不同属性的新对象,因此它们每次都会不同。您可以按别人提到的
跟踪。由于过滤器已执行,您可能希望设置一个
$watch
,并且仅在公司发生变化时创建唯一公司的新列表。实际上,我没有这样做,就得到了
10$digest()迭代次数达到的
错误

$scope.$watchCollection('companies', function(newValue) {
    $scope.filteredCompanies = $filter('uniqueCompanies')($scope.companies, 
        'companyName');
});
您还可以在母公司上设置一个监视,仅在子公司列表发生变化时创建子公司列表,并清除子公司的值:

$scope.$watch('parentCompany', function(newValue) {
  $scope.subsidiaries = [];
  for (var i = 0; i < $scope.companies.length; i++) {
    var c = $scope.companies[i];
    if (c.companyID === newValue) {
      $scope.subsidiaries.push(c);
    }
  }
  $scope.subsidiaryCompany = undefined;
});
$scope.$watch('parentCompany',函数(newValue){
$scope.subsides=[];
对于(var i=0;i<$scope.companys.length;i++){
var c=$scope.companies[i];
if(c.companyID==newValue){
$scope.subsidials.push(c);
}
}
$scope.subsidiaryCompany=未定义;
});

在选择之前在控制器中运行过滤器是否有帮助?因为过滤器每次都返回一个新对象数组,所以您需要提供一个
track by
表达式。看看这是否有区别。你能提供一些样本数据吗?这有点难理解,因为您在过滤器中重命名了属性。看起来您的数据有
companyName
companyID
subID
subName
。如果子公司拥有自己的子公司,那么规则是什么?i、 e.“GE->NBC环球->NBC广播”@Dylan-我以前没有在控制器中使用过过滤器。但是根据你的建议,我只是尝试将$filter添加到我的控制器中,然后通过
将$scope.oldCo=$filter('uniquecompanys')($scope.companys,'companyName')
进行过滤,但是$scope.oldCo出现了空值。我做得不对吗?@AndyMcCormick这样做有效-谢谢你的回复。当我得到我的数据时过滤将不起作用,因为我仍然需要所有的子公司,不管它们的母公司是什么。我想我可以将$scope.companys转储到一个数组中并减少该值,然后从该数组中提取我的公司列表,但这似乎会影响使用Angularjs的目的。谢谢!我很担心
10$digest()迭代出现的错误,但是我发现在网上谈论它的大多数地方似乎都有“忽略它”的想法。我尝试将手表添加到提琴中,它起了作用,但我的代码中似乎还有另一个问题,因为迪伦链接的提琴工作正常,但在我的实际应用程序中不起作用。当我可以正式地说它解决了问题的时候,我会回来把这个标记为最佳答案。谢谢!这非常有效,并且消除了迭代达到的错误。我一直想花一分钟来了解观察者是如何工作的,这很好地迫使我知道何时、何地以及为什么要使用它们。谢谢很高兴它起作用了。如果您正在学习,
$watch
$watchCollection
之间的差异值得注意。每
getcompanys()
函数中的
uniquecompanys
如果不进行修改,则最好设置
uniquecompanys
。由于您也在创建新对象,
$watchCollection
不会捕获对象属性的差异,例如,如果您更改公司名称。
function getCompanies(){
  $http.get("get.php?table=getcompanies").success(function(data) {
    $scope.companies = data.reduce(function (prev, cur) {
      // some code for skipping duplicates goes here                              
    }, []);
  });
}
$scope.$watchCollection('companies', function(newValue) {
    $scope.filteredCompanies = $filter('uniqueCompanies')($scope.companies, 
        'companyName');
});
$scope.$watch('parentCompany', function(newValue) {
  $scope.subsidiaries = [];
  for (var i = 0; i < $scope.companies.length; i++) {
    var c = $scope.companies[i];
    if (c.companyID === newValue) {
      $scope.subsidiaries.push(c);
    }
  }
  $scope.subsidiaryCompany = undefined;
});