0
<div>
    <ul id="myTags"></ul>
    <input type="submit" value="Submit">
</div>
$("#myTags").tagit({
    tagSource: function(request,response){
        $.ajax({
            url:"../wenda/tagMatch",
            data:{key:request.term},
            dataType:'json',
            success:function(data){
                response ($.map(data,function(item){
                    //此处的item数据的格式是这样的{id:"49",text:"asp"}
                    return{value:item.text}
                }))
            }
        })
    }
});

当输入“你好”的时候,数据库没有匹配数据,此时是用户创建标签,传给后台的是文本;当输入“a”的时候,后台有数据,匹配了“asp”“apl”两个选项,ajax返回的数据格式是{id:"49",text:"asp"}这种,当选择“asp”之后,submit时,后端希望能直接把所选标签的id值传过去(便于后期各种传参)。

如果全部传文本的话,后端需要先判断这个标签文本是否已经存储在数据库中,不在,就新建一条数据{id:"50",text:"你好"},取出id值进行后期传递;如果已经存在,则直接取其对应的id值进行后期传递。
如果传id值的话,有id值的直接取值传递;没有id值的(新创建的标签)把文本存储在数据库,取出其id值传递。这样更便利一点,处理的逻辑少一些。
图片描述

怎样才能把用户选择的标签的id值传给后端?用过这个插件的大牛请指教,谢谢!

2016-03-08 提问
1 个回答
0

思路就是把选中标签的id值先保存起来,然后把这个id值绑定在相应标签的属性上,最后提交时再取出来。

var lable_id;
$("#myTags").tagit({
    autocomplete:{
        source: function(request,response){
            $.ajax({
                url:tagMatchURL,
                data:{key:request.term},
                dataType:'json',
                success:function(msg){
                    response ($.map(msg.data,function(item){
                        return{label:item.text,value:item.text,id:item.id};//把id值返回
                    }))
                }
            })
        },
        select: function(event,ui){
            lable_id = ui.item.id;//把id值保存起来
            $("#myTags").tagit('createTag',ui.item.value);
            return false;
        }
    },
    afterTagAdded: function(event,ui){
        if(lable_id){
            $(ui.tag).children('span').attr("lable_id",lable_id);//把id值绑定到<span>标签</span>上面
            lable_id = null;
        }else {//当标签不是通过下拉选择添加的时候(如按enter键、空格键添加等),向后台发送标签文本,创建新数据(后台有查重的处理)
            var tagName = $(ui.tag).children('span').text();
            $.ajax({
                url:addTagURL,
                data:{tagName:tagName},
                dataType:'json',
                success:function(msg){
                    $(ui.tag).children('span').attr("lable_id",msg.data.id);//返回新创建标签的id,如果是重复的标签则直接返回标签的id
                }
            })
        }
    }
});

最后提交时,可以把所有创建的标签的信息提取出来:

var tagCollection = [];
$(tagUlId).find('li:not(:last) > span').each(function(){
    var tagInfo = {};
    tagInfo.id = $(this).attr('lable_id');
    tagInfo.text = $(this).text();
    tagCollection.push(tagInfo);
});
return tagCollection;

把以上所有的过程进行了一次封装:

var czd_tag = {
    insertTag: function(tagUlId,tagMatchURL,addTagURL){
        var lable_id;
        $(tagUlId).tagit({
            tagLimit: 3,
            placeholderText: "请输入标签,最多可输入3个,每个标签不超过12个字",
            autocomplete:{
                source: function(request,response){
                    $.ajax({
                        url:tagMatchURL,
                        data:{key:request.term},
                        dataType:'json',
                        success:function(msg){
                            response ($.map(msg.data,function(item){
                                return{label:item.text,value:item.text,id:item.id}
                            }))
                        }
                    })
                },
                select: function(event,ui){
                    lable_id = ui.item.id;
                    $("#myTags").tagit('createTag',ui.item.value);
                    return false;
                }
            },
            afterTagAdded: function(event,ui){
                if(lable_id){
                    $(ui.tag).children('span').attr("lable_id",lable_id);
                    lable_id = null;
                }else {
                    var tagName = $(ui.tag).children('span').text();
                    $.ajax({
                        url:addTagURL,
                        data:{tagName:tagName},
                        dataType:'json',
                        success:function(msg){
                            $(ui.tag).children('span').attr("lable_id",msg.data.id);
                        }
                    })
                    
                }
            }
        });
    },

    getTagsInfo: function(tagUlId){
        var tagCollection = [];
        $(tagUlId).find('li:not(:last) > span').each(function(){
            var tagInfo = {};
            tagInfo.id = $(this).attr('lable_id');
            tagInfo.text = $(this).text();
            tagCollection.push(tagInfo);
        })
        return tagCollection;
    },
    
    removeAllTags: function(tagUlId){
        $(tagUlId).tagit('removeAll');
        return false;
    }
    
    /**
     *  DEMO
     *
     *  <ul id="myTags" style="width:980px;margin:0 auto;"></ul>
     *  <span id="submit">submit</span><span class="cancel">取消</span>
     *  ------------------------------------------------------------------------------
     *    czd_tag.insertTag("#myTags","../wenda/tagMatch","../wenda/addTag");//调用插件
     *  $('#submit').click(function(){
     *         console.log(czd_tag.getTagsInfo("#myTags"));//获取标签的id、text值
     *  });
     *  $(".cancel").click(function(){
     *      czd_tag.removeAllTags("#myTags");//清除所有标签
     *  });
     */

};

以上的业务逻辑有一点问题是:创建新标签的过程是直接与服务器交互的,并不是最后一步提交时才与服务器通信。也就是说,当用户创建新标签时,数据库上就增加了一条数据,不论用户有没有最终提交问题或是发表文章。
比如,我发表一篇文章,创建了“哈哈”这个新标签,但是中途我又不想发表了,就把文章删除了。最终的结果就是服务器已经有这个标签了,但是没有任何与这个标签相关的内容。当下一次有人输入标签,输入“哈”的时候,就已经有了“哈哈”这个备选项,这会误导用户以为已经有人用过这个标签了,搜索这个标签相关的内容时,却发现又没有任何相关的内容……个人认为,这种处理流程还是有一点瑕疵的。
SF也有这个问题,只不过SF用了一个单独的“创建标签页面”,似乎是想把“创建新标签”这个过程与提问题、发文章分隔开,但,个人感觉还是没有避免上述的“会误导用户认为…”

如果提交时才把所有标签的文本信息一块传给服务器,就避免了上述歧义,但这时需要服务器端做一些查重、存新标签、取id值传递等一连串的业务逻辑,综合考虑还是选择了小概率事件的“让用户以为已经有人使用了这个标签”的做法。

撰写答案

推广链接