V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Aegwynn
V2EX  ›  程序员

有没有这样的前端组件?寻思许久,仍未发现合适的解决方案。

  •  
  •   Aegwynn · 2014-11-21 11:37:38 +08:00 · 3491 次点击
    这是一个创建于 3657 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 一个文本域A,可以让用户输入任意文本内容;

    • 一组标签/宏,用户通过点击或者拖拽,可以插入文本域A中的光标位置;

    • 一个文本域B,可以同步预览A中的内容(因为A中有插入标签/宏,可以同步转换)

    示例:

    用户在A中输入:亲爱的客户姓名,你于申请时间通过申请方式提交了申请事项

    其中客户姓名申请时间申请方式申请事项为标签/宏,是一个单独的label,中间无法插入。类似于淘宝、京东的搜索标签一样,右上方有个小x,可以随意去掉或者插入。

    B中提供预览效果:亲爱的张三,你于2014年11月21日通过网上交易提交了认购申请

    标签/宏可以做一个mapping来达到预览的效果,但是文本A中插入和拖拽标签/宏,感觉还没有清晰的思路。本来打算通过iframe的方式嵌入div,label之类的,后来感觉太繁琐。

    特来求助万能的v2ex,有没有类似的前端组件可以分享一下?

    14 条回复    2014-11-22 17:20:22 +08:00
    DaniloSam
        1
    DaniloSam  
       2014-11-21 11:50:25 +08:00
    LZ看一下富文本编辑器实现吧
    cornelia
        2
    cornelia  
       2014-11-21 11:51:20 +08:00
    angularjs的双向绑定?
    tsingyi
        3
    tsingyi  
       2014-11-21 11:51:44 +08:00
    能不能这样?
    ```
    <div>
    <span contenteditable>亲爱的</span><label>张三</label><span contenteditable>, 你于</span><label>2014年11月21日</label><span contenteditable>通过</span><label>网上交易</label><span contenteditable>提交了</span><label>认购申请</label>
    </div>
    ```
    kmvan
        4
    kmvan  
       2014-11-21 11:53:16 +08:00 via Android
    自己写一个呗!
    jimwoo
        5
    jimwoo  
       2014-11-21 12:34:25 +08:00
    我觉得 ng 满足了!
    Aegwynn
        6
    Aegwynn  
    OP
       2014-11-21 13:48:57 +08:00
    @tsingyi 这种方式太复杂
    @kmvan 这不先看看有没有现成的轮子,没有的话再自己创造轮子么,节省时间
    @DaniloSam 这个可以实现效果,但无法区分宏和普通文字
    @jimwoo ng是什么?
    jimwoo
        7
    jimwoo  
       2014-11-21 13:55:12 +08:00
    @Aegwynn angular~哈哈
    tremblingblue
        8
    tremblingblue  
       2014-11-21 14:06:50 +08:00
    早上刚用ng写了个内容局部高亮显示的input,不过你想要的label在编辑的时候比较麻烦,莫非用多个input来组成。。。
    akfish
        9
    akfish  
       2014-11-21 14:22:50 +08:00
    这很简单,本质上就是写一个template parser,A中渲染parser生成的AST,预览里渲染给parser传入数据后的生成结果。
    比如可以定义语法:[[标签名]]
    样例输入的纯文本表示就变成:亲爱的[[客户姓名]],你于[[申请时间]]通过[[申请方式]]提交了[[申请事项]]
    这样的parser可以通过正则式简单的实现,调用API形如:
    ```
    var parser = new Parser();
    var template = parser.parse(”亲爱的[[客户姓名]],...");
    ```
    template是一个token array:
    ```
    [{type: text, data: "亲爱的"}, {type: label, name: "客户姓名" }...]
    ```

    在A里面,你把这个array撸一遍,生成:
    ```
    <span>亲爱的</span><span class="label">客户姓名</span>...
    ```

    B里面的内容通过调用类似如下的API:
    ```
    tempate.generate({"客户姓名": "akfish", ...})
    ```
    简单的替换token array里的label token就能生成:
    ```
    <span>亲爱的</span><span class="whatever">akfish</span>...
    ```

    最核心的流程就是以上这些,剩下的CSS, JS交互神马的很容易。
    kingwrcy
        10
    kingwrcy  
       2014-11-21 14:25:44 +08:00
    楼主要的是angularjs
    Aegwynn
        11
    Aegwynn  
    OP
       2014-11-21 16:03:19 +08:00
    @tremblingblue 是的,高亮显示这都不是问题,关键是label
    @akfish 单凭这么详细的回复,就该点个赞啊。通读下来,template解析很容易实现,但有个最关键的问题:宏的完整性,比如[[申请时间]],这必须要是一个整体,避免误操作出现[[申请的时间]]这样的。
    akfish
        12
    akfish  
       2014-11-21 16:08:09 +08:00
    @Aegwynn 检查[[]]之间的标签名是否是在允许的列表内,不是的话要么报错,要么当做普通文本处理。
    或者用户的输入都当做纯文本处理,不对用户暴露这一内部表示语法,只有用UI才能插入标签。
    方法很多,就看你具体要怎么处理了。
    thonatos
        13
    thonatos  
       2014-11-21 17:28:16 +08:00
    ng或者vue


    vue.js
    http://vuejs.org/
    14
        14
    14  
       2014-11-22 17:20:22 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1259 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 18:07 · PVG 02:07 · LAX 10:07 · JFK 13:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.