AngularJS select 使用值作为值语法时不绑定

AngularJS select not binding when using value as value syntax

我正在尝试使用 AngularJS 创建一个 Select 标签。我正在使用 ngOptions 和 ngModel 进行数据绑定。

现在:假设我有如下数据源:

$scope.doesNotBind = [
        {ID: 12, Title: "12 - Does not bind"},  
        {ID: 14, Title: "14 - Does not bind"},  
    ];

$scope.doesNotBindModel = {ID: 14, Title: "14 - Does not bind"};
<select ng-options="value as value.Title for value in doesNotBind" ng-model="doesNotBindModel">
        <option value> </option>
</select>

那永远不会绑定。但是如果我这样绑定模型;有用!

$scope.doesNotBindModel = $scope.doesNotBind[1];

我使用的语法不正确还是这是预期的行为?

我创建了一个 POC 来充分展示我在说什么。

JSFiddle POC

有趣的是,当没有 as 语法(没有对象数据绑定)时,它工作得很好(在演示中也是如此)

谢谢!

编辑:我想这是预料之中的,因为他们引用了嗯?

它不具有约束力,因为它们是两个不同的对象。

创建对象时,会为其分配一个单独的内存位置。

var a = {};

var b = {};

如果你检查是否a === b,它会return你为假。因为两者是两个不同的对象。

这就是为什么

$scope.doesNotBindModel = {ID: 57, Title: "57 - Does not bind"};

不绑定而

$scope.doesBindModel = $scope.doesBind[3];

因为在后一种情况下,您指的是基于其索引的同一对象。

ngModel 按引用比较,而不是值。所以如果你使用 ng-options="value as value.Title for value in doesNotBind",那么你的 doesNotBindModel 必须是:

JavaScript:

$scope.doesNotBindModel = $scope.doesNotBind[1];

但是,如果您仍想将 doesNotBindModel 设置为 JSON 表示法,您可以将 track by value.ID 添加到 ng-options 表达式中,如下所示:

HTML:

<select ng-options="value as value.Title for value in doesNotBind track by value.ID"
        ng-model="doesNotBindModel">
</select>

它也可以通过添加 track by 表达式来工作,但是 Angular 的 ngOptions 文档不推荐这样做。

这背后的原因请参考下面的例子:

HTML:

<select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected">
  <option value="">---- not selected ----</option>
</select>

JavaScript:

$scope.values = [{
  id: 1,
  label: 'aLabel',
  subItem: { name: 'aSubItem' }
}, {
  id: 2,
  label: 'bLabel',
  subItem: { name: 'bSubItem' }
}];

$scope.selected = { name: 'aSubItem' };

出于保留选择的目的,track by 表达式始终应用于数据源的元素(在本例中为 item)。要计算元素是否被选中,我们执行以下操作:

  1. 对数组中的元素应用track by。在示例中:[1, 2]
  2. track by 应用于 ngModel 中已选择的值。

在示例中:这是不可能的,因为 track by 指的是 item.id,但是从 ngModel 中选择的值是 {name: 'aSubItem'}。因此 track by 表达式应用于错误的对象,无法找到所选元素。 <select> 始终重置为 "not selected" 选项。

实例:http://plnkr.co/edit/Hu5T1Vo3qTkrDqe5PHJy