从CustomBinding访问Knockout组件ViewModel

时间:2014-10-20 20:57:27

标签: javascript knockout.js

我正在尝试创建一个自定义的Knockout组件来包装Google Chart的图表(或任何图表库)。

理想情况下,我想使用包含图形数据的viewmodel创建一个组件。一旦使用自定义绑定绑定了该组件,每当调用更新函数时,我将使用数据访问该数组,添加新值,并告诉图表重绘。

问题是当我进入绑定处理程序的更新功能时,我看不到图形的视图模型。我该如何访问?

组件:

        ko.components.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>'
        });

结合:

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;
    }
}

更新:这是我打算如何使用绑定。 pressureValue变量将是我的主视图模型中的值,该值在后台不断更新。

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

有什么想法?我接近这个错误吗?

2 个答案:

答案 0 :(得分:3)

你在这里结合了两个不同的概念。

当使用Knockout的新组件功能时,数据绑定语法是不同的

请参阅:http://knockoutjs.com/documentation/component-custom-elements.html

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

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

Knockout将调用您的组件,并使用您从模板值提供的DOM替换自定义元素的内容。在您的情况下,模板是一个没有数据绑定的空DIV。在任何时候都不会调用您的自定义绑定。

您的组件现在应该将pressureValue observable作为params参数发送到viewModel函数。

我认为,根据您预期的自定义绑定,您需要添加这个&#34;值&#34;到viewModel

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

现在应该成为组件的模板(其中$ data是从组件的viewModel函数返回的对象的值)

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

现在应该启动自定义绑定,并希望获得您期望的结果。

我认为上面的示例中仍然缺少某些内容,因为更新绑定中的变量value已在任何地方声明,如果它是observable。需要进行一些调整,但上面的基本数据流应该是你需要的。

如果我走在正确的轨道上,请告诉我......

答案 1 :(得分:1)

您应该能够在update函数中使用ko.dataFor(element)或ko.contextFor(element)来获取ViewModel。

有关文档和示例,请参阅http://knockoutjs.com/documentation/unobtrusive-event-handling.html

编辑:如果将绑定直接放在组件上,则结果不起作用。有关正确的解决方案,请参阅Robert Slaney的回答。