0

我已经检查了尽可能多的问题,并找到了一些答案,但我被困在最后一步。我发现的大部分内容都涵盖了如何使用复选框打开事物,而不是如何关闭除已检查的内容之外的所有内容。

我有一个表格,每行有 2-3 个复选框。目标是 1)当您选中一个框时,所有其他行中的复选框都被禁用(您唯一的选择是同一行中的复选框),然后 2)当您选中同一行中的第二个框时,如果有第三个复选框,它也被禁用,最后 3) 检查第二个框启用提交按钮。我已经让#1 开始工作(尽管我认为我这样做违反了一些规则),并且我已经让 #3 开始工作了(好吧,当你只选中一个框时它会启用,这不完全是对,但可能足够接近)。禁用三按钮行中的第三个按钮让我头疼。

我使用了 VBAhole 的演示,来自How to respond to clicks on an checkbox in an AngularJS 指令?这让我有所收获。这是工作的plnkr。

html:

<tr ng-repeat="e in entities" ng-class="{active : isChecked(e.id) }" id="row{{e.id}}">
    <td>
        <label>
            <input type="checkbox" name="checkbox{{e.id}}" ng-disabled="checkThis(e.id, e.box1id)" ng-checked="isChecked(e.box1id)" ng-click="updateCheck($event, e.id)" />
            {{e.box1}}
        </label><br />
        <label>
            <input type="checkbox" name="checkbox{{e.id}}" ng-disabled="checkThis(e.id, e.box2id)" ng-checked="isChecked(e.box2id)" ng-click="updateCheck($event, e.id)" />
            {{e.box2}}
        </label><br />
        <label>
            <input type="checkbox" name="checkbox{{e.id}}" ng-disabled="checkThis(e.id, e.box3id)" ng-checked="isChecked(e.box3id)" ng-click="updateCheck($event, e.id)" />
            {{e.box3}}
        </label>
    </td>
    <td>
        <button disabled ng-disabled="!isChecked(e.id)">submit</button>
    </td>
</tr>

这是控制器(还没有将事情分解成指令):

var app = angular.module('myApp', []);
app.controller('MyCtrl', function ($scope) {
    $scope.entities = [
        { id: 10, name: "boxrow10", box1: "red11", box1id: 11, box2: "blue12", box2id: 12, box3: "blue13", box3id: 13 },
        { id: 20, name: "boxrow20", box1: "red21", box1id: 21, box2: "blue22", box2id: 22, box3: "blue23", box3id: 23  },
        { id: 30, name: "boxrow30", box1: "red31", box1id: 31, box2: "blue32", box2id: 32, box3: "blue33", box3id: 33  }
    ];

    $scope.checked = [];
    var updateChecked = function (action, id) {
        if (action == 'add') $scope.checked.push(id);
        if (action == 'remove') $scope.checked.splice($scope.checked.indexOf(id), 1);
    }

    $scope.updateCheck = function ($event, id) {
        var checkbox = $event.target;
        var action = (checkbox.checked ? 'add' : 'remove');
        updateChecked(action, id);
    };

    $scope.isChecked = function (id) {
        return $scope.checked.indexOf(id) >= 0;
    };

    $scope.checkThis = function (id, boxid) {
        var check = $scope.checked;
        var current = id;
        if (check != current && check.length == 1) {
            return current;
        } else if (check.length == 2) {
            for (var i = check.length - 2; i >= 0; i--) {
                if (check[i] === current) {
                    check.splice(i, 1);
                }
            }
            return current;
        }
    };
});

在最后一点(第二个 if 语句)中它变得非常像意大利面条,我看不出返回电流如何真正改变任何东西,但如果我删除它,那么我就不会获得禁用功能。问题是(在许多中)如果我选中了两个框并取消选中一个,它会再次启用所有行中的所有框,而不是禁用它们(因为仍然选中了一个框)。

(我知道我可以很容易地在 jquery 中做到这一点,但我的指示是不要混合流,所以......纯角度。)我已经为此努力了好几天了。任何启示将不胜感激。蒂亚!

4

2 回答 2

3

你可以很容易地只使用 angularjs 来做到这一点。

这是一个工作示例: http: //plnkr.co/GsZWG1mEcKsB7zpz6Spy

一切都基于 ng-disabled 和范围内的一些方法。

每个复选框使用其 id 和实体调用控制器中的切换方法。

控制器将选定的实体和框保留在变量中以禁用正确的复选框。

我在控制器中添加了一个实用程序方法来了解是否应该禁用复选框,因为有一些事情需要检查......

这是控制器:

app.controller('MyCtrl', function ($scope) {
        $scope.entities = [
      { id: 10, name: "boxrow10", box1: "red11", box1id: 11, box2: "blue12", box2id: 12, box3: "blue13", box3id: 13 },
      { id: 20, name: "boxrow20", box1: "red21", box1id: 21, box2: "blue22", box2id: 22, box3: "blue23", box3id: 23  },
      { id: 30, name: "boxrow30", box1: "red31", box1id: 31, box2: "blue32", box2id: 32, box3: "blue33", box3id: 33  }
    ];
    $scope.selectedEntity = null;
    $scope.selectedBoxes = [];

    $scope.toggleChecked = function(entity, boxid) {
      if (entity == $scope.selectedEntity) {
        if ($scope.selectedBoxes.length == 1 && $scope.selectedBoxes[0]  == boxid) {
          $scope.selectedEntity  = null;
          $scope.selectedBoxes = [];
          return;
        } else if ($scope.selectedBoxes.length > 0) {
          for (var box in $scope.selectedBoxes) {
            if ($scope.selectedBoxes[box] == boxid) {
              $scope.selectedBoxes.splice(box, 1);
              return;
            }
          }
        }
      }
      $scope.selectedEntity = entity;
      $scope.selectedBoxes.push(boxid);
    };

    $scope.inSelected = function(id) {
      for (var box in $scope.selectedBoxes)  {
        if ($scope.selectedBoxes[box] == id) 
          return true;
      }
      return false;
    };

    $scope.isDisabled = function(e, id) {
      return ($scope.selectedEntity 
            && $scope.selectedEntity != e)
            ||  ($scope.selectedBoxes.length >= 2 
            && !$scope.inSelected(id));
    };
});

最后,每个复选框看起来像这样:

<label>
  <input type="checkbox"  ng-click="toggleChecked(e, e.box3id)" ng-disabled="isDisabled(e, e.box3id)" />
  {{e.box3}}
</label>

正如您在 plunker 中看到的那样,此解决方案无需杂乱的代码即可满足您的 3 个要求......它可能可以通过使用服务而不是控制器的逻辑来改进,但此版本更易于理解。

于 2013-08-23T07:17:13.870 回答
1

我已经修改了您的代码,并且对plnkr进行了一些修改。您遇到的问题在这里得到了解决,但并不完美。有2个问题:

I. 一旦选择达到 2,复选框就会被禁用。

二、所有提交按钮都已启用,$scope.submitDisabled无法正常工作主要是因为$scope.updateCheck没有更新选择。

我认为您可以调试和解决这些问题:)。你需要我所做的$scope.isEnabled工作正常。

var app = angular.module('myApp', []);

app.controller('MyCtrl', function ($scope) {
  $scope.entities = [
    { id: 10, name: "boxrow10", box1: "red11", box1id: 11, box2: "blue12", box2id: 12, box3: "blue13", box3id: 13 },
    { id: 20, name: "boxrow20", box1: "red21", box1id: 21, box2: "blue22", box2id: 22, box3: "blue23", box3id: 23  },
    { id: 30, name: "boxrow30", box1: "red31", box1id: 31, box2: "blue32", box2id: 32, box3: "blue33", box3id: 33  }
  ];

  $scope.checked = [];
  $scope.checkedCount = 0;
  var updateChecked = function (action, id) {
    if (action == 'add') {
      $scope.checked.push(id);
      $scope.checkedCount++;
    }
    else if (action == 'remove') {  // Unnecessary check?
      $scope.checked.splice($scope.checked.indexOf(id), 1);
      $scope.checkedCount--;
    }
  };

  $scope.updateCheck = function ($event, id) {
    var checkbox = $event.target;
    var action = (checkbox.checked ? 'add' : 'remove');
    updateChecked(action, id);
  };

  $scope.isChecked = function (id) {
    return $scope.checked.indexOf(id) >= 0;
  };

  $scope.isEnabled = function (rowId, boxid) {
    switch($scope.checkedCount) {
      case 2: return false;
      case 1: return $scope.checked[0] == rowId;
      case 0: return true;
    }
  };

  $scope.submitDisabled = function (rowId) {
    return !($scope.checkedCount == 2 && $scope.checked[0] == rowId);
  };
});

模板是:

<!DOCTYPE html>
<html ng-app="myApp" ng-controller="MyCtrl">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js" data-semver="1.0.7" data-require="angular.js@1.2.0-rc1"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>

  <body>
    <table>
      <tbody>
        <tr ng-repeat="e in entities" ng-class="{active : isChecked(e.id) }" id="row{{e.id}}">
          <td>
            <label>
             <input type="checkbox" name="checkbox{{e.id}}" ng-disabled="!isEnabled(e.id)" ng-checked="isChecked(e.box1id)" ng-click="updateCheck($event, e.id)" />
          {{e.box1}} 
        </label><br />
        <label>
          <input type="checkbox" name="checkbox{{e.id}}" ng-disabled="!isEnabled(e.id)" ng-checked="isChecked(e.box2id)" ng-click="updateCheck($event, e.id)" />
              {{e.box2}}
            </label><br />
            <label>
              <input type="checkbox" name="checkbox{{e.id}}" ng-disabled="!isEnabled(e.id)" ng-checked="isChecked(e.box3id)" ng-click="updateCheck($event, e.id)" />
              {{e.box3}}
            </label>
          </td>
          <td>
            <button ng-disabled="submitDiasabled(e.id)">submit</button>
          </td>
        </tr>
      </tbody>
    </table>
  </body>
</html>
于 2013-08-23T06:21:37.230 回答