Add data-bind property to a boostrap-treeview node

2019-07-15 08:29发布

问题:

Is there a way to have "data-bind" properties added to a node when using the bootstrap-treeview ?

https://github.com/jonmiles/bootstrap-treeview

I have rendered a treeview, but I need to bind a click event to interact with my knockout ViewModel.

For a node, I need to add data-bind="click: ViewNodeData" to each node.

A node, once rendered, looks like this:

<li class="list-group-item node-tree" data-nodeid="13" style="color:undefined;background-color:undefined;">
  <span class="indent"></span>
  <span class="indent"></span>
  <span class="icon glyphicon"></span>
  <span class="icon node-icon"></span>
  A photo taken by me
</li>

I need to somehow add a data-bind to this node.

OR...

Maybe I need to have a knockout obervableSomething in my knockout view model, and load the JSON into that, and the data-bind that observable to the tree view - somehow?

EDIT:

I see someone has asked for this functionality to be added and has created a pull request on github - but not sure how to get the latest version WITH this additional functionality. I'm not sure the developer is still active.

https://github.com/jonmiles/bootstrap-treeview/pull/310

Is there a way to get this?

At the moment, I populate my treeview with the following:

var urialbums = '/api/Photo/GetAlbums';
$.get({ url: urialbums, contentType: "application/json" })
    .done(function (data) {
       // vm.Albums(data.to);
        $('#tree').treeview({ data: data })
            .on('nodeSelected', function (event, data) {
                if (data.levelId == 2) {
                    vm.SelectedImageID(data.id);
                    var img = document.getElementById('imgContainer');
                    img.src = data.data;
                }
        });
    });

Where vm is my ViewModel, which I bind after this:

ko.applyBindings(vm, document.getElementById("ImagesSection"));

回答1:

Note, that even if you will be allowed to add custom attributes like data-bind, it won't work if you apply bindings (ko.applyBindings) before the tree view is inserted into DOM.

Therefore in my opinion, the best way to do it is to create a custom knockout binding, where you have an access to the DOM element. For example, it could look like this:

ko.bindingHandlers.yourBindingName = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        $(element).treeview({data: getTree()}); //getTree() or use allBindings where you store the data that is needed for treeview
    }
};

By doing that, you can bind the DOM element in knockout and then create treeview for them. This technique actually applies to any jquery plugin or any library that highly relies on DOM elements.

EDIT: after you posted more of your code. I think what you want to do is to applyBindings directly after fetching the data. So in the $.get done function, you want to set the received data as the observable array in the viewmodel, and then ko.applyBindings. In the HTML, you create data-bind for #tree element, that has a custom binding. In the custom binding, you know the observable array, since it is in your vm and you can easily call $().treeview({data: [get array/object from your vm]})