0

ユーザーがクエリを入力できるようにすると同時に、ツリーから値を選択できる ComboBox を作成したいと考えています。ツリー選択を作成しようとしましたが、コードをdijit.form.ComboBoxの代わりに継承するように変更するdijit.form.Selectと、コードが壊れます。

ツリー選択用にツリーを持っていたのは次のとおりです。

dojo.declare('TreeSelect',dijit.form.Select,{
    constructor: function(widgetArgs){
        this.tree = widgetArgs.tree || new FC_Tree();
        this.initTree = widgetArgs.initTree;
        if(dojo.isFunction(this.initTree))
            this.initTree();
    },
    postCreate: function(){
        this.inherited(arguments);
        this.option = {label: '', value: 'NoValue'};
        this.tree.option = this.option;
        this.addOption(this.option);

        dojo.connect(this.tree,'onClick',this,'closeDropDown');

        dojo.connect(this.tree,'itemSelected',this,'selectOption');
    },
    selectOption: function(opt){
        this.option.label = opt.label || opt;
        this.option.value = opt.value || opt;
        this.option.id = opt.id || opt;
        this.set('value',this.option);                      
    },
    _getMenuItemForOption: function (option){
        return this.tree;
    },
    openDropDown: function(){
        this.tree.refresh();
        this.inherited(arguments);
    },
    clear: function(){
        this.tree.clear();
        this.tree.option.value = '';
        this.tree.option.label = '';
        this.tree.option.id = '';
        this.set('value',this.tree.option);
    },

    initializeTree: function(treeData) {
        // Init the tree only if needed
        dojo.forEach(treeData, function(field) {
            var store = this.tree.model.store;
            store.newItem(field);
        }, this);

    },
    setOpenCallback: function(callback){
        this.tree.setOpenCallback(callback);
    },
    resetTree: function() {
        var store = this.tree.model.store;
        store.fetch( { query: { id: "*" },  
            onItem: function(item) {
                store.deleteItem(item);
            }
        });
    }
});

コンボボックスのコードを次のように置き換えてみました:

dojo.declare('TreeSelect',dijit.form.ComboBox,{

それを修正するのを手伝ってください。前もって感謝します!

FC_Tree のコードを追加します。

dojo.declare('FC_Tree',dijit.Tree,{
    showRoot: false,
    openOnClick: true,
    noIconForNode: true,
    noMarginForNode: true,
    persist: false,
    openCallback: null,
    constructor: function(){
        if(dojo.isUndefined(arguments[0]) || dojo.isUndefined(arguments[0].model))
        {
            var forest_store = new FC_DataStore({id: 'id', label: 'label'});
            this._storeloaded = false;
            dojo.connect(forest_store,'loaded',this,function(){this._storeloaded = true;})
            this.model = new dijit.tree.ForestStoreModel({store:forest_store});
        }
    },

    setOpenCallback: function(callback){
        this.openCallback = callback;
    },

    option: {},
    itemSelected: function(item){
    },

    onClick: function(item, node, evt){
        var store = this.model.store;
        get = function(){
            return store.getValue(item, "isDir");
        };
        // on folder click mark it unselectable
        if(get("isDir")) 
        {
            this.isExpanded = true;
            this.isExpandable = true;

        }
        else
        {   //In case the item has 'onClick' delegate execute it and assign the output to 'selItem'
            var selItem = (item.onClick && item.onClick[0])? item.onClick[0](this.model.store,item.parentID[0]):item.id[0]; 

            this.option.id = item.id;
            this.option.value = item.value;
            this.option.label = item.label;
            this.itemSelected(this.option);

        }
    },

    onOpen: function(item, node){
        if(this.rootNode.item == item){
            return this.inherited(arguments);
        }

        var data = (this.openCallback != null) ? this.openCallback(item, node) : {};
        if(!data.length){
            return this.inherited(arguments);
        }
        FC_Comm.when(data,{
            onCmdSuccess: dojo.hitch(this,function(data){
                var store = this.model.store;
                var children = store.getValues(item, 'children');
                dojo.forEach(children, function(child) {
                    // don't delete child if doNotDelete flag is true
                    if(!store.getValue(child, "doNotDelete"))
                        store.deleteItem(child);
                });
                if (data) {
                    var store = this.model.store;
                    if (store) {
                        dojo.forEach(data, function(child) {
                            store.newItem(child, {parent : item, attribute: 'children'});
                        });
                    }
                }
            })
        });
    },

    refresh: function(){

        if(this._storeloaded){
            // Close the store (So that the store will do a new fetch()).
            this.model.store.clearOnClose = true;
            this.model.store.close();

            // Completely delete every node from the dijit.Tree     
            this._itemNodesMap = {};
            this.rootNode.state = "UNCHECKED";
            this.model.root.children = null;

            // Destroy the widget
            this.rootNode.destroyRecursive();

            // Recreate the model, (with the model again)
            this.model.constructor(this.model)

            // Rebuild the tree
            this.postMixInProperties();
            this._load();
            this._storeloaded = false;
        }
    },
    clear: function(){
        this.model.store.load([]);
    }
});
4

1 に答える 1

1

おそらく、このフィドルでインスピレーション/答えを見つけることができます

recursiveHunt および selectTreeNodeById関数は、アイテムのパスを ID で検索するロジックです。それは非常に過剰であり、より良い解決策を見つけることができます(jsonがどのようなデータであるか100%わからない)..

基本的には、FilteringSelect を使用して、このオブジェクト内のツリーを参照します。Tree についても、select を参照してください。次に、ツリーに対してロード関数にフックし(リフレッシュ時にも呼び出されます)、選択に対してonBlurを使用してツリーノードの選択を開始します。

var combo = new dijit.form.FilteringSelect({
    onBlur: function() {
        // called when filter-select is 'left'
        if (this.validate()) {
            // only act if the value holds an actual item reference
            var id = this.get("value");
            var name = this.get("displayedValue");
            this.tree.selectNode(id);
        }
    }
});
var tree = new dijit.Tree( {  ....
    onLoad: function() {
        combostore.setData(this.model.store._arrayOfAllItems);
    },
    onClick: function(item) {
        // uses 'this.combo', must be present
        // also, we must have the same 'base store' for both combo and model
        var _name = this.model.store.getValue(item, this.combo.searchAttr);
        this.combo.set("item", item,  false, _name);
    },
    selectNode: function(lookfor) {
        selectTreeNodeById(this, lookfor);
    },
    combo: combo // <<<<<<
});
combo.tree = tree // <<<<<<

モデルに rootId があり、select.searchAttr が tree.model.labelAttr と一致していることを確認してください。フィドルの作業サンプルを参照してください

于 2012-06-12T14:04:53.133 に答える