【问题标题】:Set initial value of text input field without triggering ng-change在不触发 ng-change 的情况下设置文本输入字段的初始值
【发布时间】:2017-04-03 04:43:12
【问题描述】:

场景是一个使用 JavaScript 和 AngularJS 的数独游戏。

数独字段是数组(列)的数组(行)。所有数组的长度都是 9。我将此数独字段命名为 matrix。函数exampleMatrix()返回这样一个已经填充了一些字段的矩阵。

updateValue(sudokuMatrix, row, col, val) 函数将矩阵sudokuMatrix 中位置行row 和列col 的字段更改为值val

function TestController($scope) {
    $scope.matrix = exampleMatrix();
    $scope.updateValue = updateValue;
    $scope.getMatrixVal = function getMatrixVal(row, col) {
        return $scope.matrix[row][col];
    };
}

我想要做的是将矩阵的每个字段显示为 HTML 中的 <input type="text"> 字段。我希望所有字段最初都设置为它们在矩阵中的值。如果文本字段的输入发生更改,我希望在 $scope.matrix 对象中更新值。

使用以下 HTML/AngularJS 代码,我可以用矩阵的值填充字段,没有问题:

<div ng-repeat="(rowIndex,row) in matrix track by $index">
    <input type="text" size="1" value="{{col}}"
           ng-repeat="(colIndex,col) in row track by $index">
</div>

当然,我还不能更新 $scope.matrix 对象中的值。

我面临的问题是

  1. 如果我更改输入字段中的值,matrix 应该会更新该值。我可以用ng-change="updateValue(matrix, rowIndex, colIndex, inputVal)" 做到这一点。
  2. 为了能够用ng-change更改范围内的matrix,我需要一个ng-model,它将字段的输入绑定到一个变量:ng-model="inputVal"
  3. 如果我添加这两行,输入字段最初不会使用范围的 matrix 对象中的值填充。

当前代码如下所示:

<div ng-repeat="(rowIndex,row) in matrix track by $index">
    <input type="text" size="1" value="{{getMatrixVal(rowIndex, colIndex)}}"
           ng-model="inputVal"
           ng-change="updateValue(matrix, rowIndex, colIndex, inputVal)"
           ng-repeat="(colIndex,col) in row track by $index">
</div>

我的猜测是,当站点生成时,ng-model 将输入字段的空值赋值给inputVal,然后立即触发ng-change。因此,矩阵的每个字段都将填充一个空值。 AngularJS 没有抛出任何错误,所以我不能确定。无论如何,我在这里不知所措,不知道如何让初始值最初写入字段,ng-change 只能在之后调用。我感谢每一个帮助。

JSFiddle:https://jsfiddle.net/30xkedmp/

JavaScript:http://pastebin.com/8cge8BXs HTML:http://pastebin.com/X0YUPU4h

【问题讨论】:

  • 能否分享一个您已部署代码的网址以便于测试?
  • 在文章末尾附加了代码的链接。抱歉,我还没有在线部署它。
  • 创建小提琴,这对我们来说很容易。 jsfiddle.net
  • 终于搞定了。在文章末尾附加链接。

标签: javascript html angularjs arrays


【解决方案1】:

你可以试试这段代码看看,我只是把你的 value 属性替换为 input 标签中的 ng-value 属性,如下图,

<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
</head>
<body ng-controller="TestController">
<div ng-repeat="(rowIndex,row) in matrix track by $index">
  <input type="text" size="1" ng-value="getMatrixVal(rowIndex, colIndex)"
         ng-model="inputVal"
         ng-change="updateValue(matrix, rowIndex, colIndex, inputVal)"
         ng-repeat="(colIndex,col) in row track by $index">
</div>
<script>
angular.module('app', []);
angular.module('app').config(['$controllerProvider', function($controllerProvider) {
  $controllerProvider.allowGlobals();
}]);

function emptyRow() {
  return [0, 0, 0, 0, 0, 0, 0, 0, 0];
}

function emptyMatrix() {
  var sudokuMatrix = [];
  for (var i = 0; i < 9; i++) {
    sudokuMatrix[i] = emptyRow();
  }
  return sudokuMatrix;
}

function updateValue(sudokuMatrix, row, col, val) {
  row = parseInt(row);
  col = parseInt(col);
  val = parseInt(val);
  sudokuMatrix[row][col] = val;
}

function exampleMatrix() {
  matrix = emptyMatrix();
  updateValue(matrix, 0, 2, 6);
  updateValue(matrix, 0, 3, 3);
  updateValue(matrix, 0, 4, 2);

  updateValue(matrix, 1, 2, 1);
  updateValue(matrix, 1, 5, 5);
  updateValue(matrix, 1, 6, 3);
  updateValue(matrix, 1, 7, 6);

  updateValue(matrix, 2, 0, 9);
  updateValue(matrix, 2, 1, 4);
  updateValue(matrix, 2, 3, 6);

  updateValue(matrix, 3, 2, 4);

  updateValue(matrix, 4, 0, 8);
  updateValue(matrix, 4, 1, 7);
  updateValue(matrix, 4, 3, 1);
  updateValue(matrix, 4, 4, 3);
  updateValue(matrix, 4, 5, 4);
  updateValue(matrix, 4, 7, 5);
  updateValue(matrix, 4, 8, 6);

  updateValue(matrix, 5, 6, 1);

  updateValue(matrix, 6, 5, 9);
  updateValue(matrix, 6, 7, 4);
  updateValue(matrix, 6, 8, 7);

  updateValue(matrix, 7, 1, 1);
  updateValue(matrix, 7, 2, 7);
  updateValue(matrix, 7, 3, 5);
  updateValue(matrix, 7, 6, 2);

  updateValue(matrix, 8, 4, 7);
  updateValue(matrix, 8, 5, 2);
  updateValue(matrix, 8, 6, 5);

  return matrix;
}

function TestController($scope) {
  $scope.matrix = exampleMatrix();
  $scope.updateValue = updateValue;
  $scope.getMatrixVal = function(row, col) {
    return $scope.matrix[row][col];
  };
}

</script>
</body>
</html>

代码 sn-p 在这里不起作用,因为它似乎不接受我指定的 angular js 版本,但其余代码运行良好。

您可以尝试用小提琴中的 ng-value 属性替换 value 属性并尝试

【讨论】:

  • 我应该知道它必须有一个指令。这正是我想要的,谢谢!对于遇到相同问题的任何人,此线程中有更多信息:stackoverflow.com/questions/23865608/…
  • 确实,在你的情况下可以使用ng-value代替ng-model,但是你这里使用的代码太多,你需要的只是单个ng-model,不需要使用ng-change , getMatrixVal 函数或“inpuVal”变量。正如我在下面的评论中提到的我的答案 - ng-model 指令是双向绑定,因此它会自动更新控制器变量; ) 看看这个问题:stackoverflow.com/questions/28717523/…
【解决方案2】:

你为什么不直接使用

<div ng-repeat="(rowIndex,row) in matrix track by $index">
    <input type="text" size="1" ng-model="matrix[rowIndex][colIndex]"
           ng-repeat="(colIndex,col) in row track by $index">
</div>

而不是

<div ng-repeat="(rowIndex,row) in matrix track by $index">
    <input type="text" size="1" value="{{getMatrixVal(rowIndex, colIndex)}}"
           ng-model="inputVal"
           ng-change="updateValue(matrix, rowIndex, colIndex, inputVal)"
           ng-repeat="(colIndex,col) in row track by $index">
</div>

【讨论】:

  • 没想到,让它更干净。但是我仍然有我写入输入字段的值不会更新控制器中的矩阵的问题。
  • ng-model 是双向绑定,因此它会在您更改视图时更新控制器中的值,并在您更改控制器值时更新您的视图
  • 你确实是对的,对不起。我的代码遇到了问题,因为我使用 updateValue(...) 方法将输入字符串解析为 int,而现在使用 ng-model 无法轻松做到这一点。我检查更改的方式无法识别字符串,在我看来,该值没有被注册。无论如何,你是绝对正确的,这个代码比其他选项简单得多(你的答案是第一个),所以我改变了我的投票。
猜你喜欢
  • 2016-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
  • 2019-04-08
相关资源
最近更新 更多