0

我的应用程序中有一个简单的导航控件,它有一个复选框列表,每个复选框代表一个标签,还有一个项目列表,每个项目都有一个或多个与之关联的标签。当检查一个或多个标签时,应显示具有这些标签的项目。

我有两个数据集,一个为每个项目列出一组标签,一个为每个标签列出一组项目。

到目前为止,我的代码如下所示:

HTML:

<div id="tag-selector" ng-controller="tagSelectorController">
   <label ng-repeat="tag in tags" style="display:block;">
      <input type="checkbox" ng-model="tag.selected"/>
       {{tag.name}}
      </label>
 </div>
 <hr>
 <div id="item-selector" ng-controller="tagSelectorController">
   <div ng-repeat="item in items" ng-show="(item.name | tagFilter:this.selection)">
       {{item.name}}
   </div>
 </div>

JS:

var app = angular.module("tagSelectorApp", []);

app.filter("tagFilter", function () {
           return function (input, selection) {
                    for (var tag in selection) {
                       if (selection[tag].items.indexOf(input) > -1) {
                          return true;
                       }
                    }
                    return false;
                  }
           });

app.controller("tagSelectorController", [
  "$scope",   
  tagSelectorController = function($scope) {
      $scope.tags = [{"name": "tag1",
                      "items": ["item1", "item3"],
                      "selected": true
                      },
                     {"name": "tag2",
                      "items": ["item1", "item2"],
                      "selected": false
                      },
                     {"name": "tag3",
                      "items": ["item3", "item1"],
                      "selected": true
                      }
                    ];

       $scope.items = [{"name": "item1",
                      "tags": ["tag1", "tag2", "tag3"]
                      },
                     {"name": "item2",
                      "tags": ["tag2"]
                      },
                     {"name": "item3",
                      "tags": ["tag1", "tag3"]
                      }
                    ];
      $scope.selection = [];
      $scope.$watch("tags | filter:{selected:true}", 
                    function (selectedTags) {
                        $scope.selection = selectedTags;
                    },
                    true);
   }
]);

angular.bootstrap(angular.element(document.getElementById("tag-selector")), ["tagSelectorApp"]);
angular.bootstrap(angular.element(document.getElementById("item-selector")), ["tagSelectorApp"]);

我遇到的问题是:虽然项目列表正确反映了初始标签选择状态,但在随后的复选框选中/取消选中时它不会改变。我的印象是,每次我选中一个复选框时,范围都会被修改,并且项目列表会被重新过滤,但情况似乎并非如此。

我错过了什么?

这是 jsfiddle 中的上述代码:http: //jsfiddle.net/2Vb2z/1/

4

1 回答 1

1

纠正你tagFilter这样的:

app.filter("tagFilter", function () {
    return function (input, selection) {
        var filterItems = [];
        for (var i=0;i< input.length;i++){
             for (var tag in selection) {
                 if (selection[tag].items.indexOf(input[i].name) > -1) {
                      filterItems.push(input[i]);
                      break;   
                 }
             }
        }
         return filterItems;
     }
});

修改您的 HTML 以仅使用 1 个控制器,以便您可以共享您的selection

<div id="tag-selector" ng-controller="tagSelectorController">
  <label ng-repeat="tag in tags" style="display:block;">
     <input type="checkbox" ng-model="tag.selected"/>
     {{tag.name}}
  </label>
<hr>

  <div ng-repeat="item in items | tagFilter:selection"> //change expression to tagFilter:selection
     {{item.name}}
  </div>
</div>

演示

如果您需要用于ng-show显示项目,请尝试以下操作:

<div ng-repeat="item in items" ng-show="isShown(item)">

将此功能添加到您的范围:

$scope.isShown = function(item){
          for (var tag in $scope.selection) {
                 if ($scope.selection[tag].items.indexOf(item.name) > -1) {
                      return true;
                 }
             }
          return false;
      }

演示

于 2014-05-01T03:28:17.733 回答