ng-click在ng-model更改后执行

时间:2015-06-11 16:52:49

标签: javascript angularjs angularjs-ng-model

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

我有这个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范围变量增加1并减少{ {1}}一个人。相反,它在变量实际更改之前传入excluded,因此我单击的第一个按钮显示-1使用/ n + 1被排除。

我能想到的解决方案是找到一些在ng-model之后绑定范围变量后执行ng-click执行的方法,或者某种方式在ng-click方法中更改$ scope.analyses对象,所以然后不需要ng-model语句?

谢谢!

编辑:btn-checkbox指令实际上需要ng-model语句。我需要这个指令来显示切换开/关以包含/排除某些分析。实现用于指示包含/排除的css的替代指令或代码将是有帮助的!

4 个答案:

答案 0 :(得分:1)

我不是相当确定我会关注,但我认为我们可以简化事情。

首先,让我们说每个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;
};

答案 1 :(得分:0)

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

如果不是添加/减去值,而是简单地跟踪数组的长度,那么一切都应该落到位。

这就是我所说的。您的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);
    };

}]);

我的意思是我并不确切地知道你的分析对象是什么样的,但是这应该可以帮助你将这些计数绑定到实际的数组长度。

答案 2 :(得分:0)

我不确定我是否关注,但$scope.set中的条件逻辑在include属性增加之前正在查找真值。这显然不会发生在您的代码实施的in this plunker示例中。

唯一的区别是我确保include是前三个分析中的属性&amp;&amp;设为true。您的代码按预期工作,您的分析对象不是。

答案 3 :(得分:0)

如果不是传递分析,那么你可以从函数的范围中获取它。

我创建了一个 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切换包含/排除,而不是仅递增。

以及更新的设置功能:

$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
 }
};