Twitter typeahead将自定义数据添加到数据集

Nou*_*l.M 6 javascript jquery autocomplete twitter-bootstrap bootstrap-typeahead

twitter typeahead用来显示对我来说很好的类别建议.问题在于子类别的显示.如果a category has sub-categories then expand/collapse icon与建议一起显示,如果用户选择其中一个子类别必须在其下面显示,我已经成功显示部分但是cannot update the dataset有一个类型,这样当用户选择一个子类别时它应该是显示在输入中.Please use keyboard on Jsfiddle because i have tried only in keypress.以下是我的json数组

JSFIDDLE 在这里

[{
    "id": "38",
    "value": "Entertaintment",
    "parent_id": "27",
    "children": "1",
    "childCategories": [{
        "id": "28",
        "value": "Movies",
        "parent_id": "38"
    }, {
        "id": "29",
        "value": "Sports",
        "parent_id": "38"
    }]
}, {
    "id": "40",
    "value": "eeen",
    "parent_id": "27",
    "children": "1",
    "childCategories": [{
        "id": "41",
        "value": "een child 1",
        "parent_id": "40"
    }]
}, {
    "id": "41",
    "value": "een child 1",
    "parent_id": "40",
    "children": "0",
    "childCategories": false
}]
Run Code Online (Sandbox Code Playgroud)

我尝试过以下方法:

_onEnterKeyed: function onEnterKeyed(type, $e) {
    var cursorDatum, topSuggestionDatum;
    cursorDatum = this.dropdown.getDatumForCursor();
    topSuggestionDatum = this.dropdown.getDatumForTopSuggestion();
    //My custom condition, if category has children show sub-categories below 
    if (cursorDatum.raw && cursorDatum.raw.children == "1") {
        //below line is my failed try  
        //this.dropdown.updateChild('',cursorDatum.raw.childCategories,false); 
        var that = this, onSuggestionClick, onSuggestionMouseEnter, onSuggestionMouseLeave;
        var childHTML='';
        $('.ttchild').remove();
        //adding the sub-categories to dropdown
        $.each(cursorDatum.raw.childCategories,function(i,v){
            childHTML += '<div class="tt-suggestion ttchild"><div class="suggestions"><span>'+this.value+'</span></div></div>';
        });
        $(childHTML).insertAfter('.tt-cursor');
        return;
    }

    if (cursorDatum) {
        this._select(cursorDatum);
        $e.preventDefault();
    } 
    else if (this.autoselect && topSuggestionDatum) {
        this._select(topSuggestionDatum);
        $e.preventDefault();
    }
},

//This is my custom function trying to update the dataset, but i know its totally wrong.
updateChild: function updateChild(query,childs) {
    var that = this;
    this.query = query;
    this.canceled = false;
    this.source(query, render);

    function render(childs) {
        if (!that.canceled && query === that.query) {
            that._render(query, childs);
        }
    }
},
Run Code Online (Sandbox Code Playgroud)

JSFIDDLE 在这里

例如:娱乐类别有子类别电影和体育.

希望任何人都能帮助我....

use*_*789 2

编辑 v.2

我再次重构,现在完美了。

我删除了之前的编辑并重构了onEnterKeyed功能,如下所示

var dataSet = this.dropdown.datasets[0];

// childHTML is replaced by childDom
// var childHTML='';
var childDom = $('<div></div>');
$('.ttchild').remove();
$.each(cursorDatum.raw.childCategories,function(i,v){

    var div = $('<div class="tt-suggestion ttchild"></div>');
    div.append('<div class="suggestions"><span>'+this.value+'</span></div>');


    var suggestion = v;

    // TODO console log this is duplicated from dataset
    var datasetKey = "ttDataset", valueKey = "ttValue", datumKey = "ttDatum";


    // this is what makes it show in the input box
    // set these data for the child element.
    div.data(datasetKey, dataSet.name);
    div.data(valueKey, dataSet.displayFn(suggestion));
    div.data(datumKey, suggestion);

    childDom.append(div);
});

// childHtml is replaced by childDom
$('.tt-cursor').append(childDom.children());
Run Code Online (Sandbox Code Playgroud)

已弃用的编辑 v.1

重构了我的解决方案,现在它按预期工作。

我删除了之前的编辑并在getSuggestionNode方法中添加了这一行。

for (var key in suggestion.childCategories) {
    var value = suggestion.childCategories[key];
    $el.append(getSuggestionNode(value));
}
Run Code Online (Sandbox Code Playgroud)

下面已弃用

解决了你的问题,尽管你需要改进。

// I added this line
// add the child nodes to the suggestions.
suggestions = suggestions.reduce(function(res, num) { res.push(num); for (var i=0;i<num.children;i++) res.push(num.childCategories[i]);  return res; }, [])

// nodes are calculated based on suggestions
// but child nodes are not added to suggestions so their data is not set (see below line)
nodes = _.map(suggestions, getSuggestionNode);

// inside the suggestions.map function
// here .data sets the necessary values required to render the input on cursor change.
// since child nodes are not mapped they are ignored.
$el = $(html.suggestion).append(that.templates.suggestion(suggestion))
    .data(datasetKey, that.name)
    .data(valueKey, that.displayFn(suggestion))
    .data(datumKey, suggestion);
Run Code Online (Sandbox Code Playgroud)

因此,您不需要自定义updateChild函数,尽管我不知道如何实现下拉列表,但此解决方案会将子级添加到下拉列表中并立即显示它们,而无需在父节点中按 Enter 键。您应该自行配置。