javascript - Accessing Knockout Component ViewModel from CustomBinding - Stack Overflow

I am trying to create a custom Knockout ponent to wrap around a Google Chart's graph (or any chart

I am trying to create a custom Knockout ponent to wrap around a Google Chart's graph (or any chart library for that matter).

Ideally I would like to make a ponent with a viewmodel that holds the graph data. Once that ponent is bound using a custom binding, whenever the update function is called I would access that array with the data, add the new value, and tell the graph to redraw.

The problem is when I am inside the update function of the bindinghandler, I cannot see the graph's view model. How can I access this?

Component:

        koponents.register('line-graph', {
        viewModel: function(params) {
            var self = this;
            self.data = new google.visualization.DataTable(
            {
                cols: [{id: 'index', label: '', type: 'number'},
                       {id: 'value', label: '', type: 'number'}]

            }, 0.6);
            self.currentPoint = 1;
            self.lastValue = null;
        },
        template:
            '<div></div>'
        });

Binding:

ko.bindingHandlers.lineGraph = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
         var observable = valueAccessor();

         if(observable != null){
             //Here, the viewmodel and all properties of the bindingContext correspond to the main viewmodel, not the graph's viewmodel
             viewModel.data.addRow([viewModel.currentPoint++, value]);
             drawChart();
         }

         viewModel.lastValue = value;
    }
}

Update: Here is how I plan to use the binding. The pressureValue variable would be a value in my main viewmodel that is being updated constantly in the background.

<line-graph data-bind="lineGraph: pressureValue"></line-graph>

Any thoughts? Am I approaching this incorrectly?

I am trying to create a custom Knockout ponent to wrap around a Google Chart's graph (or any chart library for that matter).

Ideally I would like to make a ponent with a viewmodel that holds the graph data. Once that ponent is bound using a custom binding, whenever the update function is called I would access that array with the data, add the new value, and tell the graph to redraw.

The problem is when I am inside the update function of the bindinghandler, I cannot see the graph's view model. How can I access this?

Component:

        ko.ponents.register('line-graph', {
        viewModel: function(params) {
            var self = this;
            self.data = new google.visualization.DataTable(
            {
                cols: [{id: 'index', label: '', type: 'number'},
                       {id: 'value', label: '', type: 'number'}]

            }, 0.6);
            self.currentPoint = 1;
            self.lastValue = null;
        },
        template:
            '<div></div>'
        });

Binding:

ko.bindingHandlers.lineGraph = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
         var observable = valueAccessor();

         if(observable != null){
             //Here, the viewmodel and all properties of the bindingContext correspond to the main viewmodel, not the graph's viewmodel
             viewModel.data.addRow([viewModel.currentPoint++, value]);
             drawChart();
         }

         viewModel.lastValue = value;
    }
}

Update: Here is how I plan to use the binding. The pressureValue variable would be a value in my main viewmodel that is being updated constantly in the background.

<line-graph data-bind="lineGraph: pressureValue"></line-graph>

Any thoughts? Am I approaching this incorrectly?

Share Improve this question edited Oct 21, 2014 at 11:15 BrennanU asked Oct 20, 2014 at 20:57 BrennanUBrennanU 751 silver badge9 bronze badges 2
  • A ponent isn't a binding, is your template value missing some data binding in the example above, as well as var self=this; ? Can you also show the HTML where the knockout ponent is being used ? – Robert Slaney Commented Oct 21, 2014 at 2:21
  • I added my planned usage to the post, I also seem to have missed copying the var self = this;. Thanks! – BrennanU Commented Oct 21, 2014 at 11:15
Add a ment  | 

2 Answers 2

Reset to default 3

You are bining two different concepts here.

When using the new ponent feature of Knockout the data-bind syntax is different

refer to : http://knockoutjs./documentation/ponent-custom-elements.html

<line-graph params="value: pressureValue"></line-graph>

or

<div data-bind="ponent: {name: 'line-graph', params: {value: pressureValue}}"></div>

Knockout will invoke your ponent and replace the contents of your custom element with the DOM you supply from the template value. In your case, the template is an empty DIV with no data-bind. At no point is your custom binding invoked.

Your ponent should now have the pressureValue observable sent into the viewModel function as the params argument.

I think, based on what your custom binding is expected, you need to add this "value" to the viewModel

viewModel: function(params) {
    ...
    self.value = params.value;
}

Your template of the ponent should now bee ( where $data is the value of the object returned from the viewModel function of the ponent )

template: '<div data-bind="lineGraph: $data.value"><div>'

This should now fire your custom binding and, hopefully, get the result you expect.

I think there is still something missing from your samples above as the variable value in your update binding is declared anywhere, should that have been observable. A bit of tweaking will be required but the basic data flow above should be what you need.

Please let me know if I'm on the right track...

You should be able to use ko.dataFor(element) or ko.contextFor(element) from inside the update function to get the ViewModel.

See http://knockoutjs./documentation/unobtrusive-event-handling.html for documentation and an example.

Edit: Turns out this doesn't work if you put the binding directly on the ponent. For the proper solution see Robert Slaney's answer.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745356181a4624131.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信