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 来充分展示我在说什么。
有趣的是,当没有 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
)。要计算元素是否被选中,我们执行以下操作:
- 对数组中的元素应用
track by
。在示例中:[1, 2]
- 将
track by
应用于 ngModel
中已选择的值。
在示例中:这是不可能的,因为 track by
指的是 item.id
,但是从 ngModel
中选择的值是 {name: 'aSubItem'}
。因此 track by
表达式应用于错误的对象,无法找到所选元素。 <select>
始终重置为 "not selected" 选项。
我正在尝试使用 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 来充分展示我在说什么。
有趣的是,当没有 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
)。要计算元素是否被选中,我们执行以下操作:
- 对数组中的元素应用
track by
。在示例中:[1, 2]
- 将
track by
应用于ngModel
中已选择的值。
在示例中:这是不可能的,因为 track by
指的是 item.id
,但是从 ngModel
中选择的值是 {name: 'aSubItem'}
。因此 track by
表达式应用于错误的对象,无法找到所选元素。 <select>
始终重置为 "not selected" 选项。