关于实现下拉选框的默认选中问题

问题描述

angular项目中,点击编辑人员操作,会在表单中默认显示选择的人员的信息,信息以下拉选框的形式展现,每个下拉选框都是一个指令。这时,技术机构指令和管理部门指令均以同一个字段:department作为他们的选项。他们两个都是部门,只是类型不同。对于同一个人员,只能有一个部门,所以要默认显示技术机构或管理部门。

排查原因

首先看一下我们的两个指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
<div class="form-group" ng-show="showInstrumentUser">
<label class="col-sm-4 control-label">技术机构</label>
<div class="col-sm-8">
<yunzhi-instrument-user ng-model="data.department" data-district="params.district" data-config="{departmentType: '技术机构'}"></yunzhi-instrument-user>
</div>
</div>
<div class="form-group" ng-show="showManagementDepartment">
<label class="col-sm-4 control-label">管理部门</label>
<div class="col-sm-8">
<yunzhi-management-department data-district="params.district" ng-model="data.department"></yunzhi-management-department>
</div>
</div>
...

上面是我点击编辑后,根据id获取的人员有一个部门字段,内容为管理部门,这时应该默认选中管理部门。但是并没有选择上。所以让我们删除一下技术机构再看一下效果。

1
2
3
4
5
6
7
8
...
<div class="form-group" ng-show="showManagementDepartment">
<label class="col-sm-4 control-label">管理部门</label>
<div class="col-sm-8">
<yunzhi-management-department data-district="params.district" ng-model="data.department"></yunzhi-management-department>
</div>
</div>
...

这回默认选中了管理部门。这里不妨大胆的猜测一下原因:

由于技术机构的存在,我们将部门传进指令中,没有对应的技术机构,所以部门就成了空。

让我们将技术机构再放回来,然后调换一下两个指令的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
<div class="form-group" ng-show="showManagementDepartment">
<label class="col-sm-4 control-label">管理部门</label>
<div class="col-sm-8">
<yunzhi-management-department data-district="params.district" ng-model="data.department"></yunzhi-management-department>
</div>
</div>
<div class="form-group" ng-show="showInstrumentUser">
<label class="col-sm-4 control-label">技术机构</label>
<div class="col-sm-8">
<yunzhi-instrument-user ng-model="data.department" data-district="params.district" data-config="{departmentType: '技术机构'}"></yunzhi-instrument-user>
</div>
</div>
...

可以看到管理部门同样被默认选择上了,说明我们上面的猜测正确。

由于ng-model在angularjs中会使数据双向绑定,当前面的技术机构没有对应的对象存在时,它就会选中空值,这时又将这个空值绑定在ng-model上。两个指令的ng-model都绑定的是统一数据,所以后面的管理部门在取选中的时候,就是根据空值来选择的,当然选择不上了。

解决办法

我们最开始在controller中通过id获取对象时,直接将返回的对象中的属性给ng-model了,导致两个指令对应同一参数。

1
2
3
4
5
6
7
...
self.getOneById = function(id) {
PersonnelPersonnelsupervisefileService.getOneById(id, function(data) {
$scope.data = data;
};
};
...

既然两个指令绑定同一变量会混乱,那我让他们绑定不同的变量是不是就可以了呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
$scope.instrumentUser = undefined; // 初始化技术机构
$scope.managementDepartment = undefined; // 初始化管理部门
self.getOneById = function(id) {
PersonnelPersonnelsupervisefileService.getOneById(id, function(data) {
$scope.data = data; // 赋值
$scope.params.district = data.department.district; // 为区域赋值
// 如果数据的部门是管理部门,为管理部门赋值
if (data.department.departmentType.pinyin === "guanlibumen") {
$scope.managementDepartment = data.department;
// 如果数据的部门是技术机构,为技术机构赋值
} else if (data.department.departmentType.pinyin === "jishujigou") {
$scope.instrumentUser = data.department;
}
});
};
...

首先定义两个变量,用来绑定不同的指令,当我们编辑的人员的部门的类型是技术机构,就为技术机构这个对象赋值;如果为部门类型是管理部门,就为管理部门赋值;否则均不赋值。然后再让两个指令绑定不同的变量。

1
2
3
4
5
6
7
8
9
10
11
12
<div class="form-group" ng-show="showInstrumentUser">
<label class="col-sm-4 control-label">技术机构</label>
<div class="col-sm-8">
<yunzhi-instrument-user ng-model="instrumentUser" data-district="params.district" data-config="{departmentType: '技术机构'}"></yunzhi-instrument-user>
</div>
</div>
<div class="form-group" ng-show="showManagementDepartment">
<label class="col-sm-4 control-label">管理部门</label>
<div class="col-sm-8">
<yunzhi-management-department data-district="params.district" ng-model="managementDepartment"></yunzhi-management-department>
</div>
</div>

到此,问题解决。但是肯定有细心的小朋友发现了,你在这里将部门用两个变量来表示,但对于人员来说这两个都不是我们要的字段,那保存的时候怎么绑定部门呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$scope.$watch('[instrumentUser, managementDepartment]',
function(newValue) {
var instrumentUser = newValue[0]; // 技术机构
var managementDepartment = newValue[1]; // 管理部门
// 当选择了技术机构,为监督抽查人员的部门字段赋值
if (instrumentUser && instrumentUser.id) {
$scope.data.department = instrumentUser;
// 当选择了管理部门,为监督抽查人员的部门字段赋值
} else if (managementDepartment && managementDepartment.id) {
$scope.data.department = managementDepartment;
// 当什么都没选时,为监督抽查人员的部门字段赋空值
} else {
if ($scope.data) {
$scope.data.department = instrumentUser = managementDepartment;
}
}, true);

在这里我们监听一下技术机构和管理部门,当他们选择的时候,将他们选择的值赋给人员的部门。

总结

这次的问题中,显然我们的解决办法显得并不是多么高深的方法,很简单。所以解决问题的关键在快速的定位问题产生的原因,当原因找到后,问题也就迎刃而解了。

坚持原创技术分享,您的支持将鼓励我继续创作!