ng-model改变后点击执行

ng-click to execute after ng-model changes

我想知道是否有一种方法可以让 ng-click 函数接受一个范围变量,该函数在同一范围变量的 ng-model 值发生变化后执行。我在名为 analyses 的列表中有一个 analysis 对象的列表,该列表具有(除其他外)一个 include 布尔属性。它们在 html 中显示为按钮复选框,可以按到 include/exclude。

我有这个html:

Number of bisulfite sequences: {{included}} used / {{excluded}} excluded
<div ng-repeat="analysis in analyses"><br><label class="btn btn-success" 
ng-model="analysis.include" ng-click="set(analysis.include)" btn-checkbox>

这是控制器中的代码:

$scope.analyses = some_list_of_analyses
$scope.included = 0
$scope.excluded = $scope.analyses.length

$scope.set = function(include){

//more code to execute involving $scope.analyses

  if(include){
    $scope.included += 1
    $scope.excluded -= 1
  }
  else{
    $scope.excluded += 1
    $scope.included -= 1
  }
}

现在,假设我从一个分析列表开始,如您在初始化中看到的那样,所有分析都被排除在外,当我单击一个按钮时,它应该将 included 范围变量增加一个并减少excluded 加一。相反,它在变量实际更改之前传入 analysis.include,因此我单击的第一个按钮显示 -1 已使用/已排除 n+1。

我能想到的解决方案是要么找到一些方法让 ng-click 在范围变量绑定到 ng-model 之后执行,要么找到一些方法来更改 ng- 中的 $scope.analyses 对象单击方法,那么不需要 ng-model 语句?

谢谢!

编辑:btn-checkbox 指令实际上需要 ng-model 语句。我需要此指令为 including/excluding 某些分析显示切换 on/off。实现 css 以指示 inclusion/exclusion 的替代指令或代码会有所帮助!

我不是相当确定我遵循,但我认为我们可以简化事情。

首先,假设每个 analysis 都有一个 属性 称为 included

这使您可以像这样编写几个方法:

$scope.included = function() {
  var count = 0;
  for(var i = 0; i < $scope.analyses.length; i++) {
    if($scope.analyses[i].included) {
      count++;
    }
  }
  return count;
};

$scope.excluded = function() {
  var count = 0;
  for(var i = 0; i < $scope.analyses.length; i++) {
    if(!$scope.analyses[i].included) {
      count++;
    }
  }
  return count;
};

我会让你进行重构以保持干燥。然后你的 UI 可以做这样的事情:

Number of bisulfite sequences: {{included()}} used / {{excluded()}} excluded
<div ng-repeat="analysis in analyses"><br>
<label class="btn btn-success" ng-model="analysis" ng-click="set(analysis)" btn-checkbox>

而你的点击可以很简单(注意我们现在传入的是分析对象,你可以去掉ng-model属性):

$scope.set = function(analysis) {
  $scope.analysis.included = !$scope.analysis.included;
};

我的建议是改变您跟踪包含/排除值的方式。

如果不是 adding/subtracting 从值中简单地跟踪数组的长度,那么一切都应该到位。

这就是我要说的。您的 HTML 可能如下所示:

<div ng-controller="solutionController">
Number of bisulfite sequences: {{included.length}} used / {{analyses.length - included.length}} excluded
<div ng-repeat="analysis in analyses">
    <br />
    <label class="btn btn-success" ng-click="include(analysis)" btn-checkbox=""></label>
</div>

你的控制器可能看起来像这样:

angular.module("routerApp").controller("solutionController", ["$scope", function($scope){
    $scope.included = [];
    $scope.analyses = ["sodium", "sulfur", "calcium"];

    $scope.include = function(includeMe){
        $scope.included.push(includeMe);
    };

}]);

我的意思是我不确切地知道你的分析对象是什么样子等等,但这应该让你起来 运行 将这些计数绑定到实际的数组长度。

我不确定我是否遵循,但您在 $scope.set 中的条件逻辑正在寻找包含 属性 增加之前的真值。这显然没有发生,正如 in this plunker 您的代码示例所展示的那样。

唯一不同的是,我已经确保include是前三个分析的属性 && 设置为true。您的代码按预期工作,您的分析对象不是。

如果不是传入 analysis.included 而是从函数的作用域中获取它会怎样

我创建了一个 plunkr来演示

基本上HTML:

 Number of bisulfite sequences: {{included}} used / {{excluded}} excluded

<div ng-repeat="analysis in analyses">
  <br />
  <label class="btn btn-success" ng-model="analysis.include"  btn-checkbox>
    <button ng-click="set($index)">Click Me!</button>
  </label>
</div>

所以在这里,您传入 $index 以便您知道在控制器的 $scope 上查看哪个。那么在你的控制器中:

$scope.set = function(i){

 var include = $scope.analyses[i].include;
 //more code to execute involving $scope.analyses

 if(include){
  $scope.included += 1
  $scope.excluded -= 1
 }
 else{
  $scope.excluded += 1
  $scope.included -= 1
 }
};

它似乎在 plunkr 中有效。包含的上升,排除的下降

更新:新 Plunkr 切换 included/excluded 而不是仅递增。

以及更新的集合函数:

$scope.set = function(i){

 $scope.analyses[i].include = !$scope.analyses[i].include;

 include = $scope.analyses[i].include

 //more code to execute involving $scope.analyses

if(include){
  $scope.included += 1
  $scope.excluded -= 1
 } else {
  $scope.excluded += 1
  $scope.included -= 1
 }
};