在居民选择组件的编写中我起初的想法是实现如上图这样的效果——显示居民的姓名、电话号码、身份证号,并根据小区和楼栋进行分组,但是在分组这里出现了一些bug。
我再获取居民时是通过先获取所有的居民再通过.filter进行筛选来获取所需的居民。

residents = residents.filter(residents =>
  this.isContained(districtIds, residents.houses.map(houses => houses.unit.building.village.community.id))
)
  isContained(numbers: Array<Number>, newNumbers: Array<Number>): boolean {
    return newNumbers.filter((x) => {
      return numbers.includes(x);
    }).length != 0;
  }

其中isContained函数用来判断两个数组是否有交集,如果有则返回true,这样的话只要该居民在指定范围内有房屋就会被获取到。
但是在用groupBygroupValue进行分组时就出现了问题

 groupBy(resident: Resident) {
    return resident.houses[0].unit.building.id;
  };

  groupValue(key: string | object, children: Resident[]): Building {
    const building = children[0].houses[0].unit.building;
    Assert.isDefined(building.name, 'name must be defined');
    Assert.isDefined(building.village.name, 'name must be defined');
    return building;
  }

起初我想直接按照第一个房屋进行分类,但是测试后发现如果该居民在其他区域也有房屋,并且是第一位那么就会按这个房屋进行分类,虽然居民属于该管理区域但是分类的类别不属于该管理区域,这很明显就不符合我们的需求。
于是我进行了如下改动:
起初我想的是只需要在groupBygroupValue中加入判定,在收到的resident中寻找在管辖范围内的房屋,在进行返回。

  groupBy(resident: Resident) {
    const ids = resident.houses.map(houses => houses.unit.building.village.community.id);
    const index = ids.indexOf(this.districtIds[0]);
    return resident.houses[index].unit.building.id;
  };

groupValue(key: string | object, children: Resident[]): Building {
    const buildings = children[0].houses.map(houses => houses.unit.building);
    const communityIds = buildings.map(buildings => buildings.village.community.id);
    const index = communityIds.indexOf(this.districtIds[0]);
    const building = buildings[index];
    Assert.isDefined(building.name, 'name must be defined');
    Assert.isDefined(building.village.name, 'name must be defined');
    return building;
}

其中的this.districtIds是在ngOnInit中调用相应M层方法得到的。

 this.districtService.getDistrictsOfCurrentLoginUser(DISTRICT_TYPE.community.value)
.subscribe(districts => {
  const districtIds = districts.map(value => value.id);
        this.districtIds = districtIds;
        console.log("ngOnInit");
        console.log(this.districtIds);
        ...
}

但是在运行时会发生报错——TypeError: Cannot read properties of undefined (reading 'districtIds'),即this为空,之后尝试在groupBy中进行这样的输出——console.log(this);,结果果然为undefined;
在谷歌上查询后发现有人的情况和我有一点相似——都是出现了this为undefined,但是他的问题是在一个回调函数中使用this,当它被执行时,范围是不同的。
比如我们在编译器中输入如下代码:

    var Bob = {
      sname: "鲍勃",
      friends: ["Jack", "Rose", "Tom", "Jerry"],
      intr() {
        this.friends.forEach(function (ele) {
          console.log(this.sname + "认识" + ele);@此行发生报错
        });
      }
    }

编译器会在@所处行发生报错,并会给出解决方法——改为箭头函数即

intr() {
        this.friends.forEach((ele) => {
          console.log(this.sname + "认识" + ele);
        });
      }

所以个人猜测此处的groupBy函数也被当作了回调函数,但是此处将方法改为箭头函数显然不适用,经过查询又发现了另一种方法——用bind方法将this与该方法进行绑定。它会创建一个与原来函数主体相同的新函数,新函数中的this指向传入的对象。
我们可以在构造函数中调用此方法如下所示

  constructor(private residentService: ResidentService,
              private districtService: DistrictService) {
    this.groupBy = this.groupBy.bind(this);
    this.groupValue = this.groupValue.bind(this);
  }

之后我们再在此处使用this指针就可以像我们所想的那样区执行。

03-05 13:59