如何制作一个selectAll复选框并触发每个复选框上的ng-click的每个功能?

时间:2015-05-15 03:15:00

标签: javascript angularjs checkbox underscore.js lodash

我有一些代码,当您单击复选框时,它将执行ng-click。这是它的JS。

$scope.selectTitle = function(evt, selected){
        evt.stopPropagation();
        var filtered = _.findWhere($scope.selectedTitles, {id: selected.id});
        var index = _.indexOf($scope.selectedTitles, selected);
        if(selected === filtered){
            $scope.selectedTitles.splice(index, 1)
        }
        else{
            $scope.selectedTitles.push(selected);
        }
        console.log('titles', $scope.selectedTitles, 'filtered', filtered, 'index', index);
     };

在一个包含ng-repeat和ng-click代码的表格中,所以我使用.stopPropagation()来阻止激活表格的ng-click功能。

现在我需要选中所有复选框。这是我的代码。

$scope.selectAll = function (filteredTitles) {
        if ($scope.selectedAll) {
            $scope.selectedAll = false;
        } else {
            $scope.selectedAll = true;
        }
        _.forEach(filteredTitles, function(cpPortfolioItem) {
            cpPortfolioItem.Selected = $scope.selectedAll;
            if(cpPortfolioItem.Selected){
                $scope.selectTitle();
            }
     });

当我跑的时候。发送TypeError: Cannot read property 'stopPropagation' of undefined时出错。

我无法删除stopPropagation,因为它阻止了我之前说的话。你能给我一些关于我如何选择所有复选框并调用每个复选框的ng-click功能的建议吗?提前谢谢。

2 个答案:

答案 0 :(得分:1)

一些想法。

为什么要使用selectedAll添加范围?应该只是控制器内的私有var。

var selectedAll = false;
$scope.selectAll = function(){
      selectedAll = !selectedAll; // quick toggle.
      _.forEach(filteredTitles, function(title){
                    title.isSelected = selectedAll;
       }
}

然后你的复选框应该直接进入title.isSelected状态。单独或使用selectAll更改它会很容易。

请参阅:https://docs.angularjs.org/api/ng/directive/ngChecked

<input ng-checked="title.isSelected" .../>

'title'实际上是你的ng-repeat数据对象。

另外我建议你在ng-repeat中使用一个指令。

示例指令:

angular.module('appName')
    .directive('portfolioItem', function() {
        return{
            restrict:'E',  // Element only style
            replace:true,
            templateUrl:'portfolioItem.view.html',
            scope:{
                data:'='  // binds the attribute into your scope
            }
            // You can add a controller here as well. 
        };
    });

然后为“portfolioItem.view.html”

创建一个脚本ng-template
<script ng-template="portfolioItem.view.html">
    <section class="item">
     {{data}}  
     <input ng-checked="data.isSelected" ... />
    </section>
</script>

https://docs.angularjs.org/api/ng/directive/script

如果我可以帮助你更多的话。我认为你的选择项功能应该改变。将数据推送到工厂,然后可以成为所有控制器的主干。这就是我们的工作,减少您的观察者并提高您处理数据的能力。

 angular.module('appName')
        .factory('DataManager', DataManager);

    function DataManager($log, $timeout, ItemModel) {
        var mngr, config = getConfig();  // any default values

        $log.debug('DataManager Init');

        mngr = {
            CurrentSearchTerm: null,
            Items: [],
            Abort: abort,
            GetData: getData,  // Function call to get data.
            GetMoreResults: getMoreResults
        };

        function getData(){
            dataService.getData().then(function(response){
             //  ...parse data, etc...loop and :
             mngr.Items.push(parsedDataItem);
            };
        }


        return mngr;
   }

然后你的控制器将重复关闭DataManager.Items(或过滤它将是Underscore或Angular)。有意义吗?

答案 1 :(得分:0)

这不是最漂亮的解决方案,但是,这会做两件事,如果已定义则只处理evt,并将该元素从selectTitle传递到selectAll。这是最少改变代码的解决方案。一般情况下,只需在复选框上使用ng-model就可以在没有selectTitle的情况下离开。

$scope.selectTitle = function(evt, selected){
    if(evt) evt.stopPropagation();
    var filtered = _.findWhere($scope.selectedTitles, {id: selected.id});
    var index = _.indexOf($scope.selectedTitles, selected);
    if(selected === filtered){
        $scope.selectedTitles.splice(index, 1)
    }
    else{
        $scope.selectedTitles.push(selected);
    }
    console.log('titles', $scope.selectedTitles, 'filtered', filtered, 'index', index);
 };

-

$scope.selectAll = function (filteredTitles) {
        if ($scope.selectedAll) {
            $scope.selectedAll = false;

        } else {
            $scope.selectedAll = true;

        }
        _.forEach(filteredTitles, function(cpPortfolioItem) {
            cpPortfolioItem.Selected = $scope.selectedAll;
            if(cpPortfolioItem.Selected){
                $scope.selectTitle(null, cpPortfolioItem);
            }
     })};