首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >僵尸框架网络聊天中的建议列表问题

僵尸框架网络聊天中的建议列表问题
EN

Stack Overflow用户
提问于 2020-03-04 11:11:21
回答 1查看 388关注 0票数 2

我刚刚在使用react.js的bot框架网络聊天(v-4)中添加了自动建议/自动完成功能。但是有一些问题我需要解决;

(1.)在获得建议的同时,我想把我在网络聊天中键入的单词变成结果建议列表中的Bold。我这样做了,但我现在面临的问题是,它只使第一个字母的粗体(如你可以在图像中看到),我想让它大胆,即使它在一个sentance。

(2.)当我从建议列表中选择一个选项时,必须关闭它。它关闭其他选项,但所选选项不是。(如图像所示)。我也想把它关了。

3.) --我想用向上/向下箭头从建议列表中选择选项。

请在下面的链接中找到图片,

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-24 00:14:35

对于你的第一个问题,可能有两种方法。要做到这一点,您可以使用indexOf在建议中查找用户文本的索引,然后将文本分割为多个React元素,其中一个元素被粗体显示。如果您想像现在这样使用replace,那么这可能是一个使用dangerouslySetInnerHTML的好机会

代码语言:javascript
复制
<div className="SuggestionParent" id="Suggestion1">
  {this.state.suggestions.map(suggestion => (
    <div className="Suggestion" onClick={this.handleSuggestionClick} >
      <div dangerouslySetInnerHTML={this.getSuggestionHtml(suggestion)} />
    </div>
  ))}
</div>

“危险”警告是因为您需要确保不允许用户提供任何可能出现在内部HTML中的值,否则他们可以注入脚本标记。只要您的建议是从一个固定的数据库和数据是安全的,那么您可能会没事。否则,您必须对HTML进行净化,在这种情况下,完全不使用dangerouslySetInnerHTML可能会更容易。如果我们确实设置了内部HTML,那么我们可以使用replace直接将HTML标记应用于字符串:

代码语言:javascript
复制
getSuggestionHtml(suggestion) {
  const lowerCaseSuggestion = suggestion.toLowerCase();
  return {
    __html: lowerCaseSuggestion.includes(this.state.suggestionTypedText) ? lowerCaseSuggestion
      .replace(this.state.suggestionTypedText, `<b>${this.state.suggestionTypedText}</b>`) : lowerCaseSuggestion
  };
}

关于你的第二个问题,你说你已经解决了。我可以看到,您正在使用布尔开关暂时关闭对WEB_CHAT/SET_SEND_BOX动作的响应方式。

对于第三个问题,在计算UI将如何工作时,您必须问自己许多设计考虑,比如“如果用户在使用箭头键时查看建议会发生什么?”“在用户按enter之前,是否应该在”发送“框中预览突出显示的建议?我希望找到一个预先存在的自完成组件,您可以使用它而不是构建自己的组件,因为这已经解决了所有这些潜在的缺陷。不幸的是,两个突出的反应性自动完成包(这里这里)都有相同的两个问题:

  1. 它们目前没有被维护
  2. 目标输入包含在组件中,因此您不能将组件连接到预先存在的输入。

但是,它们都是开源的,因此我们可以根据它们来建模我们自己的自动完成功能。我将指导您了解基本功能,您可以根据您的意愿对其进行扩展。

键盘事件通常使用onKeyDown属性以React方式处理。我把它放在一个包含Web和您的建议父母的元素上:

代码语言:javascript
复制
<div className={ROOT_CSS} onKeyDown={this.handleKeyDown.bind(this)}>
  <div className={WEB_CHAT_CSS + ''}>
    <ReactWebChat

这将处理所有按键,因此您需要一种方法来路由到函数以获得正确的键。您可以使用switch语句,但是反应-自动完成的源代码使用查找对象,我认为这是明智的。

代码语言:javascript
复制
keyDownHandlers = {
  ArrowDown(event) {
    this.moveHighlight(event, 1);
  },
  ArrowUp(event) {
    this.moveHighlight(event, -1);
  },
  Enter(event) {
    const {suggestions} = this.state;
    if (!suggestions.length) {
      // menu is closed so there is no selection to accept -> do nothing
      return
    }
    event.preventDefault()
    this.applySuggestion(suggestions[this.state.highlightedIndex]);
  },
}

handleKeyDown(event) {
  if (this.keyDownHandlers[event.key])
  this.keyDownHandlers[event.key].call(this, event)
}

我将上下箭头的功能集中到一个函数中:moveHighlight。您需要在状态中定义一个新属性,以跟踪键盘选择了哪个建议。我不让名字highlightedIndex反应-自动完成。

代码语言:javascript
复制
moveHighlight(event, direction) {
  event.preventDefault();
  const { highlightedIndex, suggestions } = this.state;
  if (!suggestions.length) return;
  let newIndex = (highlightedIndex + direction + suggestions.length) % suggestions.length;
  if (newIndex !== highlightedIndex) {
    this.setState({
      highlightedIndex: newIndex,
    });
  }
}

对于要应用建议的enter键,您需要集中您的功能,使其工作方式与鼠标单击相同。

代码语言:javascript
复制
async handleSuggestionClick(event) {
  await this.applySuggestion(event.currentTarget.textContent);
}

async applySuggestion(newValue) {
  await this.setState({ typingChecking: "false", suggestions: [], highlightedIndex: 0 });
  this.state.suggestionCallback.dispatch({
    type: 'WEB_CHAT/SET_SEND_BOX',
    payload: {
      text: newValue,
    }
  });
  await this.setState({ typingChecking: "true" });
}

最后,确保使用highlightedIndex属性以不同方式呈现突出显示的索引。

代码语言:javascript
复制
getSuggestionCss(index) {
  return index === this.state.highlightedIndex ? HIGHLIGHTED_CSS : SUGGESTION_CSS;
}

. . .

<div className="SuggestionParent" id="Suggestion1">
  {this.state.suggestions.map((suggestion, index) => (
    <div className={this.getSuggestionCss(index)} key={index} onClick={this.handleSuggestionClick} >
      <div dangerouslySetInnerHTML={this.getSuggestionHtml(suggestion)} />
    </div>
  ))}
</div>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60524754

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档