5

一个小小的邮件模板搜索排序,前端交互相互拉扯,有这么难吗?

 1 year ago
source link: https://www.daozhao.com/10921.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一个小小的邮件模板搜索排序,前端交互相互拉扯,有这么难吗?

如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!

一个小小的邮件模板搜索排序,前端交互相互拉扯,有这么难吗?

最近来了个需求:给现有邮件模板增加搜索功能。但是仅仅是一个如此小的需求,因为新来的交互决定对现有前端功能进行摧毁式大改 ,其预期效果版本竟然是现有交互改版之前的那个版本。。。

这一开倒车的行为招到我的强烈反对,跟交互多次拉锯战后,最终同意听我的在现有结构上进行新增改动。 没错,就是这么硬气,因为她给的理由无法说服改回老版本。

效果大致如下

file

如果搜索关键词既命中模板名称,又命中了模板目录,则模板名称排在前面。

file

因为现有的模板信息接口已经全部返回,所以本功能全部由前端完成,前端在全量数据里面进行搜索,排序及展示。

接口返回的数据结构类似

[{
    name: "目录1",
    code: 'a001',
    type: 'CATEGORY',
    children: [{
        name: "目录2",
        code: 'a002',
        type: 'CATEGORY',
        children: [{
            name: "目录22",
            code: 'a0022',
            type: 'CATEGORY',
        }, {
            name: "模板21",
            code: 'm001',
            type: 'TEMPLATE',
        }]},
        {
            name: "模板1",
            code: 'm001',
            type: 'TEMPLATE',
        }
    ]
}]

type为TEMPLATE的为模板,type为CATEGORY的为目录,并且可能下面并没有模板。

鉴于搜索关键字会命中目录和模板,需要在处理数据的时候把各个目录和模板名称收集起来,故在原有的处理逻辑里面加入collection进行收集,只需要判断collection中各个元素是否包含关键字就能判断命中情况了。

const templateHandler = (arr = [], parents = [], collection = []) => {
  const list = arr.filter(item => {
    const paths = [...parents, item];
    const key = paths.map(item => item.code).join('/');
    if (item.type === 'TEMPLATE') {
      collection.push({
        type: 0,
        label: item.name,
        paths,
        key,
      })
      return true;
    } else if (item.type === 'CATEGORY') {
      item.children = templateHandler(item.children || [], paths, collection).list;
      if (item.children.length > 0)  {
        collection.push({
          type: 1,
          label: item.name,
          paths,
          key,
        })
        return true;
      }
    }
  });
  return {
    list,
    collection,
  }
};

上述处理会将空目录(目录22)过滤掉,同时处理好待搜索集collection,为了排序比较方便,我们将TEMPLATE类型的type设置为0,CATEGORY类型的为1。

file

接下来我们完成搜索逻辑

function searchHandler(collection, keyword) {
    return collection.filter(item => item.label.includes(keyword)).map(item => {
      const labelPaths = item.paths.map(item => item.name);
      const index = labelPaths.slice().reverse().findIndex(it => it.includes(keyword));
      return {
        idx: index,
        data: item,
      }
    }).sort((a, b) => {
      if (a.data.type === b.data.type) {
        return a.idx <= b.idx ? -1 : 1;
      } else {
        return a.data.type < b.data.type ? -1 : 1;
      }
    })
}

设置idx为了方便后续排序

我们试着搜索下“1”,看看结果如何

file

符合预期,模板在前,目录在后。

搜索“目录”,结果依然符合预期

file

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK