在表格单元格上使用$ watch

时间:2015-12-18 15:49:50

标签: angularjs angularjs-ng-repeat

我需要根据表格单元格更改中的输入框的值更新触发更新。该表是针对$ resource调用的结果使用ng-repeat进行的。

关键是我需要在每次更改时更新2个不同的值。 1是同一个表行内的另一个单元格,第二个是表格本身的外部。这似乎阻止了在ng-repeat级别使用特定控制器。

我创建了这个plunkr试图帮助。 http://plnkr.co/edit/773WhoUvWoUZ40AfuzMO?p=preview

// Code goes here
angular.module('plunker', [])
.controller('ItemCtrl', function ($scope) {
  $scope.user_votes = 100;
  $scope.items = [
      {item: "Foo1", description: "Really Fancy Foo", total_votes: 0, my_votes: 0},
      {item: "Foo2", description: "Boring Foo", total_votes: 0, my_votes: 0},
      {item: "Widget 1", description: "Base widget 1", total_votes: 0, my_votes: 0},
      {item: "Big Widget", description: "Humongous Widget", total_votes: 0, my_votes: 0},
      {item: "FooBar", description: "FooBar in Gold", total_votes: 0, my_votes: 0}
  ];


     // This doesn't work, but I am not sure why.
     $scope.$watch('item.my_votes', function(newVal, oldVal){
       $scope.user_votes = $scope.user_votes - newVal.my_votes;
       newVal.total_votes = newVal.total_votes + newVal.my_votes;
     });
});

html代码是

<!DOCTYPE html>
<html ng-app="plunker">

<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.1.x" src="http://code.angularjs.org/1.1.5/angular.min.js" data-semver="1.1.5">       </script>
<script src="script.js"></script>
</head>

<body ng-controller="ItemCtrl">
<div>You have {{ user_votes }} votes remaining</div>
<table>
  <thead>
    <tr>
      <th>Item</th>
      <th>Description</th>
      <th>My Votes</th>
      <th>Total Votes</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="item in items">
      <td>{{ item.item }}</td>
      <td>{{ item.description }}</td>
      <td><input name="votes" ng-model="item.my_votes"/></td>
      <td>{{ item.total_votes }}</td>
    </tr>
  </tbody>
</table>
<button ng-click="saveForm">Cast Votes</button>
</body>
</html>

2 个答案:

答案 0 :(得分:0)

首先,控制器范围内没有单个项目,因为ng-repeat创建了自己的隔离范围(docs)。这就是为什么在你改变你的模型后没有发生任何事情的原因。在这种情况下,您可以采用不同的方法来实现实时重新加载。您可以对项目数组($ scope。$ watchCollection)执行深度监视,也可以使用ng-change与ng-model组合使用,如下所示:

HTML

<div>You have {{ user.left }} votes remaining</div>
<table>
  <thead>
    <tr>
      <th>Item</th>
      <th>Description</th>
      <th>My Votes</th>
      <th>Total Votes</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="item in items">
      <td>{{ item.item }}</td>
      <td>{{ item.description }}</td>
      <td><input name="votes" type='number' ng-model="item.my_votes" ng-change='recalc()'></td>
      <td>{{ item.total_votes + item.my_votes }}</td>
    </tr>
  </tbody>
</table>
<button ng-click="saveForm">Cast Votes</button>

JS

$scope.user = {
  base: 100,
  left: 100
}

$scope.items = [
  {item: "Foo1", description: "Really Fancy Foo", total_votes: 0, my_votes: 0},
  {item: "Foo2", description: "Boring Foo", total_votes: 0, my_votes: 0},
  {item: "Widget 1", description: "Base widget 1", total_votes: 0, my_votes: 0},
  {item: "Big Widget", description: "Humongous Widget", total_votes: 0, my_votes: 0},
  {item: "FooBar", description: "FooBar in Gold", total_votes: 0, my_votes: 0}
];

$scope.recalc = function() {
  $scope.user.left = $scope.user.base;
  for(var i = 0; i < $scope.items.length; i++) {
    $scope.user.left -= ($scope.items[i].total_votes + $scope.items[i].my_votes);
  }
}

Plnkr

答案 1 :(得分:0)

为什么不在这里使用ng-change?并将你手表中的内容放在一个可以调用ng-change的函数中。

<td><input name="votes" ng-model="item.my_votes" ng-change="watchFunction(item.my_votes, {{item.my_votes}})"/></td>

其中第一个参数是新值,第二个参数是旧值。 (如果你需要旧的价值)