Angularjs更新视图但不更新模型

时间:2014-12-09 19:57:08

标签: angularjs html-select angularjs-model angularjs-watch

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

Mi问题是:我有一个依赖选择,当' Master'选择更改,'奴隶'视图得到更新,但不是它的模型。 WEIRD。

示例代码:

<!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

3 个答案:

答案 0 :(得分:1)

@ Shomz的回答是一种方法,虽然replace似乎有点像黑客。

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

考虑它的另一种方法是:如果您没有查看(slavemaster如何更新<select> $watcher),例如对控制器进行单元测试的情况。

实现这一点的正确方法实际上是通过ng-model - 所以我不同意这一点与@Shomz。

我还建议你评估为什么你需要主人和奴隶互相遮蔽。如果是这种情况,则应使用相同的<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>

{{1}}

答案 1 :(得分:1)

Angular根据模型更改和基于用户与视图交互的模型更新视图。通过使用ng-selected手动更改所选选项,angular没有看到用户选择新选项,因此不会更新slave。由于slave上次设置控件上的选定选项后没有更改,因此它不会更新所选选项。我认为您不应该同时使用ng-modelng-selected。我认为这是完全有道理的,并不是角度的错误,ng-selected只是不打算以这种方式使用。想想这段代码:

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

slave的价值应该是什么?应该选择哪个选项?你已经在代码中设置了两个选项,角色对html选择应该做什么?它应该忽略你对“奴隶”价值的设定吗?它是否应忽略ng-selected属性,如果masterm2,则应选择奴隶2?假设您将master设置为m1,这会导致ng-selected使所选选项成为从属1.如果用户将选项更改为从属2,该怎么办?然后ng-selected选项不正确。

如果要在更改主数据时对从属值进行一次性设置,则应创建一个监视以在值更改时运行代码:

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

答案 2 :(得分:0)

Angular的方法是直接更改slave模型,而不仅仅是DOM(ng-selected基本上只设置selected属性,如果它的计算结果为true,则不然。从技术上讲,你可以通过添加一个也可以更新模型的观察器来解决这个问题,但重写它听起来更好。

这是一个例子,它有点草率,但替换是我可以做的最快的事情,而不是实际编写一些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

相关问题