【问题标题】:AngularJS: refresh ng-options when property source object changesAngularJS:属性源对象更改时刷新ng-options
【发布时间】:2016-06-01 21:18:59
【问题描述】:

完整说明: 我有具有多个属性的选项列表(不仅仅是键值对):

[
  {
    id: 1,
    name: "111",
    some: "qqq"
  },
  {
    id: 2,
    name: "222",
    some: "www"
  }
];

并选择定义为:

<select name="mySelect" id="mySelect"
  ng-options="option.name for option in opts track by option.id"
  ng-model="mod1"></select>

根据应用逻辑,额外属性可能会发生变化:

{
  id: 2,
  name: "222",
  some: "www1"
}

但 Select 中的实际列表并没有改变! 但是,如果名称更改,则整个 optionList 将被刷新。

简而言之,您可以在 JSFiddleJSFiddle 上查看演示。我准备了两个非常相似的例子:

  1. 单击按钮时,只会更新额外的属性
  2. 单击按钮时 - 额外的属性和键都会收到新值

有人知道解决办法吗?

更新

现在我正在使用update + delay + update 解决方案解决这个问题:

this.click = function(){
  $scope.opts = {};
  $timeout(function() {
    $scope.opts = { /* NEW OBJECT */};
  }, 0);
}

【问题讨论】:

  • 这在文档页面上有详细讨论:docs.angularjs.org/api/ng/directive/ngOptions。 “请注意,$watchCollection 对对象的属性(或集合中的项目,如果模型是数组)进行浅比较。这意味着更改比对象/集合内的第一级更深的属性不会触发重新渲染”
  • 嗯,谢谢指出。我虽然“第一级”是指所有属性,但不包括对象,例如{name: "111", id: 1, some: {name: "111-1", id: "1-1"}}。所以在这种情况下,some.name 的变化应该被忽略......

标签: angularjs ng-options angularjs-ng-options


【解决方案1】:

好的,所以我认为我明白你想要什么,即能够选择一个选项,因为列表在 DOM 中呈现后其嵌套值可能已更改。

基于这种理解,我相信我创建的 plunker 为您说明了一个解决方案。如果您选择其中一个选项,并在输入字段中更改子值,双向绑定将更新模型。

基本上,它接受用户选择,并在选择更改时重新分配所选对象以引用选项数组中的原始选项。这将允许发生双向绑定。如果您查看代码,您将看到输入字段正在更新选项列表本身 ($scope.options),其中 - 因为正在显示的模型是 $scope.formData .model.

https://plnkr.co/edit/DLhI7t7XBw9EbIezBCjI?p=preview

HTML

<select 
  name="mySelect"
  id="mySelect"
  ng-model="formData.model"
  ng-change="onChange(formData.model)"
  ng-options="option.name for option in options track by option.id"></select>

  SELECTED CHILD: {{formData.model.child.name}}

<hr>

<div ng-repeat="option in options">
  Child Name for {{ option.name }}: <input ng-model="option.child.name">
</div>

JS

  $scope.onChange = function(option) {

    angular.forEach($scope.options,function(optionItem){
      if (optionItem.id == option.id){
         $scope.formData.model = optionItem;
      }
    })


  }

  $scope.options = [
    {
      id: 1,
      name: "111",
      child: {
        id: 11,
        name: "111-1"
      }
    },
    {
      id: 2,
      name: "222",
      child: {
        id: 22,
        name: "222-1"
      }
    }
  ];

  $scope.formData = {
    model: $scope.options[0]
  };

【讨论】:

  • 我更新了初始描述:添加了指向 JSFiddle 的新链接,具有更清晰的解决方案,没有嵌套对象。但是,您的代码正是我所拥有的。而且您的解决方案几乎可以工作:) 谢谢。我仍然有的最后一个问题:1)选择选项“222”2)更新整个$scope.options集合(例如,您更新现有对象中的值),但我需要立即更新完整集合(来自$http)。结果SELECTED CHILD 不会更新(仍然显示旧值)。 3)但是当您更改选择中的值时-您的解决方案再次起作用fork
  • 我的错...我只需要从click 方法调用$scope.onChange($scope.formData.model);。感谢您的解决方案。它可以正常工作并替换track by option.id 语句...现在它只是多余的...奇怪的是角度不这样做
【解决方案2】:

只要您想应用所做的更改,请致电 $apply

$scope.$apply();

这将告诉 AngularJS 刷新。

【讨论】:

  • 如果影响模型的逻辑异步执行,那么是的,这将是解决方案的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-01
  • 1970-01-01
  • 2021-05-06
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多