4

请注意,这与 stackoverflow 上 99% 的相关问题相反。

我的问题是:我有一个依赖选择,当“主”选择发生变化时,“从”视图会更新,但不是模型。诡异的。

示例代码:

<!DOCTYPE html>
<html ng-app>

<head>
  <script src="https://code.angularjs.org/1.3.5/angular.js"></script>
</head>

<body>
  <select ng-model='master'>
    <option value='m1'>Master 1</option>
    <option value='m2'>Master 2</option>
  </select>
  <select ng-model='slave'>
    <option value='Slave 1 selected' ng-selected='master == "m1"'>Slave 1</option>
    <option value='Slave 2 selected' ng-selected='master == "m2"'>Slave 2</option>
  </select>
  {{ slave }}
</body>

</html>

更改主选择时,您可以看到选择发生变化,但绑定 {{ slave }} 的打印值没有变化。

链接到 plunker:http ://plnkr.co/edit/LjaKgTTfBlczkGuCIhZ1

4

3 回答 3

1

@Shomz 的答案是一种方法,尽管它replace看起来有点像黑客。

没有更新的原因slave是因为 Angular 在开发人员不知情的情况下更改 ViewModel 非常小心。通常,ViewModel 应由控制器更改以响应外部事件或由 View 更改 - 以响应用户操作。在这种情况下,更改将是响应selected所选从属设备上更改的属性,因此 Angular 不会更改slave

另一种思考方式是:如果您没有视图(即),将如何slave更新以响应更改,例如对控制器进行单元测试的情况。master<select>

事实上,实现这一点的正确方法是通过$watcher- 所以我不同意@Shomz 在这一点上。

我还建议评估为什么您需要主服务器和从服务器相互跟踪。如果是这种情况,您应该使用相同的ng-model

<select ng-model="master2" 
       ng-options="val.k as val.v for val in [{k: 'm1', v: 'Master1'}, {k: 'm2', v: 'Master2'}]">
</select>
<select ng-model="master2" 
       ng-options="val.k as val.v for val in [{k: 'm1', v: 'Slave 1'}, {k: 'm2', v: 'Slave 2'}]">
</select>   
于 2014-12-09T20:17:15.407 回答
1

Angular 根据模型更改更新视图,并根据用户与视图的交互更新模型。通过使用手动更改所选选项ng-selected,angular 没有看到用户选择新选项,因此不会更新slave。并且自从slave上次在控件上设置所选选项以来没有更改,因此不会更新所选选项。我认为你不应该一起使用ng-modelng-selected。我认为这完全有道理,并且不是 Angular 中的错误,ng-selected 并不意味着以这种方式使用。想想这段代码:

$scope.buttonClicked = function () {
  $scope.slave = "Slave 1 selected";
  $scope.master = "m2";
};

be的值slave应该是多少,应该选择哪个选项?您已经在代码中设置了这两个选项,角度应该对 html 选择做什么?它应该忽略您对“从”值的设置吗?它是否应该忽略ng-selected表示它应该选择 slave 2 if masteris的属性m2?假设您设置masterm1,这会使ng-selected所选选项成为从属 1。如果用户随后将选项更改为从属 2 怎么办?那么这个ng-selected选项是不正确的。

如果你想在master改变时一次性设置slave的值,你应该创建一个watch在值改变时运行代码:

$scope.$watch('master', function(newValue, oldValue) {
  if (newValue == 'm1') {
    $scope.slave = 'Slave 1 selected';
  } else if (newValue == 'm2') {
    $scope.slave = 'Slave 2 selected';
  } else {
    $scope.slave = undefined;
  }
});
于 2014-12-09T22:59:50.940 回答
0

对此的 Angular 方法是直接更改从属模型,而不仅仅是 DOM(ng-selected基本上只是设置selected属性,如果它评估为真,没有别的)。从技术上讲,您可以通过添加一个也会更新模型的观察者来解决这个问题,但重写它听起来是一个更好的主意。

这是一个例子,它有点草率,但替换是我在不实际编写一些 JS 的情况下能做的最快的事情(但你明白了):

  <select ng-model='master' ng-change="slave = master.replace('m', 's')">
    <option value='m1'>Master 1</option>
    <option value='m2'>Master 2</option>
  </select>
  <select ng-model='slave'>
    <option value='s1' >Slave 1</option>
    <option value='s2' >Slave 2</option>
  </select>

http://plnkr.co/edit/WT7vb7yvtcvaUPUwGXdI?p=preview

于 2014-12-09T20:06:41.373 回答