当前位置: 首页 > Web前端 > HTML

ng-select中分组选项时遇到的问题

时间:2023-03-28 18:59:12 HTML

在编写住户选择组件时,我最初的想法是实现上图所示的效果——显示住户的姓名、电话、身份证号,以及按照地区和建筑进行分组,但是分组有一些bug。当我再次获取居民时,我首先获取所有居民,然后通过.filter过滤以获取所需的居民。居民=居民。filter(residents=>this.isContained(districtIds,residents.houses.map(houses=>houses.unit.building.village.community.id)))isContained(numbers:Array,newNumbers:Array):boolean{returnnewNumbers.filter((x)=>{returnnumbers.includes(x);}).length!=0;}isContained函数用来判断两个数组是否有交集,如果有则返回true,所以只要居民在指定范围内有房子,就会获取。但是用groupBy和groupValue分组时会出现问题groupBy(resident:Resident){returnresident.houses[0].unit.building.id;};groupValue(key:string|object,children:Resident[]):Building{constbuilding=children[0].houses[0].unit.building;Assert.isDefined(building.name,'namemustbedefined');Assert.isDefined(building.village.name,'namemustbedefined');定义');返回建筑物;}一开始我想直接按照第一个房子来分类,但是经过测试发现,如果住户在其他区域也有房子而且是第一个,那么就会按照这个房子来分类,虽然住户属于toThemanagementareabutclassifiedcategory不属于管理区,这显然不符合我们的需求。于是我做了如下修改:一开始我以为只需要在groupBy和groupValue中加一个判断,从接收到的住户中搜索辖区内的房子,然后返回即可。groupBy(resident:Resident){constids=resident.houses.map(houses=>houses.unit.building.village.community.id);constindex=ids.indexOf(this.districtIds[0]);返回resident.houses[index].unit.building.id;};groupValue(key:string|object,children:Resident[]):Building{constbuildings=children[0].houses.map(houses=>houses.unit.building);constcommunityIds=buildings.map(buildings=>buildings.village.community.id);constindex=communityIds.indexOf(this.districtIds[0]);constbuilding=建筑物[索引];Assert.isDefined(building.name,'namemustbedefined');Assert.isDefined(building.village.name,'namemustbedefined');returnbuilding;}其中的this.districtIds是在ngOnInit中调使用相关M层方法得到的。this.districtService.getDistrictsOfCurrentLoginUser(DISTRICT_TYPE.community.value).subscribe(districts=>{constdistrictIds=districts.map(value=>value.id);this.districtIds=districtIds;console.log("ngOnInit");控制台.log(this.districtIds);...}但是在运行时会报错—TypeError:Cannotreadpropertiesofundefined(reading'districtIds'),即this为空,然后尝试输出这样的输出在groupBy——console.log(this);,结果确实是undefined,google了一下,发现有人的情况和我有点相似——都显示this是undefined,但是他的问题是用this在一个回调函数,执行时作用域不同。例如,我们在编译器中输入如下代码:varTest={name:"name",friends:["a","b","c","d"],intr(){this.friends.forEach(function(friendName){console.log(this.name+"Knowledge"+friendName);@Thislinehasanerror//尝试在这里输出this,发现这是undefined});}}测试.intr();Compiler会在@所在的行报错,并给出解决方案——改成一个箭头函数,即intr(){this.friends.forEach((ele)=>{console.log(this.sname+"knowledge"+ele);//这里尝试输出this,发现这是一个Test对象//这是因为箭头函数本身没有this指针,调用的话会直接继承上一层的指针});所以我个人猜测这里的groupBy函数也是作为回调函数使用的,但是这里把方法改成箭头函数显然不适用。查询后发现还有一个方法——使用bind方法将this绑定到方法上。它创建了一个与原函数体相同的新函数,新函数中的this指向传入的对象。通过bind方法绑定后,无论在什么情况下被调用,函数都会一直绑定到它的第一个参数对象上。我们可以在构造函数中调用这个方法,如下所示this.groupValue=this.groupValue.bind(this);然后我们就可以在这里使用这个指针来执行我们想要的了。这里虽然解决了问题,但是我们仍然不知道为什么会出现这样的问题。查看ng-select的源码后,上述问题可以简化为如下情况:test1(){console.log(this);}test2(test:()=>void){测试();}ngOnInit():void{this.test2(this.test1)}执行后,我们会发现控制台打印出来的test1中的this是undefined。如果我们想要得到我们想要的结果,就需要使用bind方法将this指针的指向改为constructor(){this.test1=this.test1.bind(this);然后我们再去看看之前给出的例子,你会发现两者本质上都是一个问题。对于多层嵌套的对象,内部方法的this指向离被调用函数最近的对象,所以我们在使用某些方法的时候,如果需要传递一个函数的时候,需要注意this的使用,避免错误。