我知道有一些非常明显的东西我完全没有注意到,所以非常感谢您的帮助。
我有一个功能,提供两个下拉列表。它们包含相同的数据(该功能允许两个人之间进行交易,这些人就是数据),但我希望它们各自获得自己的数据副本。
该功能的另一个部分是,通过在第一个下拉列表中选择A人,我希望禁用第二个下拉列表中的A人,反之亦然,因此我让ng-options
标签注意对象上的disabled
属性。
我的问题是,即使使用诸如Lodash的clone
方法来正确创建“新”数组,每次我仅访问一个数组中的A人(并明确不访问另一个数组)时,我总是看到当我触摸A人时,该对象在两个数组中都被更新,这让我感到困惑。
这感觉像是一个基于Javascript的低级问题(标准的PEBCAK,我感觉我显然误解或完全遗漏了某些基本内容),也许涉及一些AngularJS渲染相关的乐趣,但是...出了什么问题?
angular.module('myApp', [])
.controller('weirdDataController', function($scope) {
$scope.$watch('manager1_id', () => {
if (angular.isDefined($scope.manager1_id) && parseInt($scope.manager1_id, 10) > 0) {
$scope._disableManagerInOtherDropdown(false, $scope.manager1_id);
}
});
$scope.$watch('manager2_id', () => {
if (angular.isDefined($scope.manager2_id) && parseInt($scope.manager2_id, 10) > 0) {
$scope._disableManagerInOtherDropdown(true, $scope.manager2_id);
}
});
$scope._gimmeFakeData = () => {
return [{
manager_id: 1,
manager_name: 'Bill',
disabled: false
},
{
manager_id: 2,
manager_name: 'Bob',
disabled: false
},
{
manager_id: 3,
manager_name: 'Beano',
disabled: false
},
{
manager_id: 4,
manager_name: 'Barf',
disabled: false
},
{
manager_id: 5,
manager_name: 'Biff',
disabled: false
},
];
};
const data = $scope._gimmeFakeData();
$scope.firstManagers = _.clone(data);
$scope.secondManagers = _.clone(data);
$scope._disableManagerInOtherDropdown = (otherIsFirstArray, managerId) => {
const disableManagers = manager => {
manager.disabled = manager.manager_id === managerId;
};
if (otherIsFirstArray) {
$scope.firstManagers.forEach(disableManagers);
} else {
$scope.secondManagers.forEach(disableManagers);
}
console.log('Is the first item the same??', $scope.firstManagers[0].disabled === $scope.secondManagers[0].disabled);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="weirdDataController">
<div class="col-xs-12 col-sm-6">
<select class="form-control" ng-model="manager1_id" ng-options="manager.manager_id as manager.manager_name disable when manager.disabled for manager in firstManagers track by manager.manager_id">
<option value="" disabled="disabled">Choose one manager</option>
</select>
<select class="form-control" ng-model="manager2_id" ng-options="manager.manager_id as manager.manager_name disable when manager.disabled for manager in secondManagers track by manager.manager_id">
<option value="" disabled="disabled">Choose another manager</option>
</select>
</div>
</div>
<br /><br />
$scope
相关的所有内容都丢了进去。下面是具体流程:
- 初始化时,我获取数组,然后为每个下拉列表克隆一份副本。
- 当每个下拉列表更改模型属性(对象 ID)时,我使用一个 scope 监听器调用一个方法来处理在相反列表中禁用所选对象/人员。
- 在这个方法内部,我确定要迭代哪个列表/数组,并标记禁用的对象。
- 在该方法结束时,我会进行一个简单的 console.log 调用以检查给定对象的值。出于快速和方便起见,我只获取索引为 0 的项目。
- 我的期望:一个对象的
disabled
值为true
,而相反的对象的值为false
。但实际看到的是两者的值都为 true(假设选择了下拉列表中的第一个“真实”项目)。
_.cloneDeep()
。 - Patrick Roberts