【问题标题】:Accessing Knockout Component ViewModel from CustomBinding从 CustomBinding 访问 Knockout 组件 ViewModel
【发布时间】:2014-11-02 05:04:41
【问题描述】:

我正在尝试创建一个自定义的 Knockout 组件来环绕 Google Chart 的图表(或与此相关的任何图表库)。

理想情况下,我想制作一个带有保存图形数据的视图模型的组件。一旦使用自定义绑定绑定了该组件,每当调用更新函数时,我都会使用数据访问该数组,添加新值,并告诉图形重绘。

问题是当我在绑定处理程序的更新函数中时,我看不到图形的视图模型。我怎样才能访问它?

组件:

        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>

有什么想法吗?我是不是在错误地处理这个问题?

【问题讨论】:

  • 组件不是绑定,您的模板值是否缺少上面示例中的某些数据绑定以及var self=this;?您还可以显示正在使用淘汰组件的 HTML 吗?
  • 我在帖子中添加了我的计划用法,我似乎也错过了复制 var self = this;。谢谢!

标签: javascript knockout.js


【解决方案1】:

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

使用 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 函数中。

我认为,根据您的自定义绑定的预期,您需要将此“值”添加到 viewModel

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

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

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

现在应该会触发您的自定义绑定,并希望得到您期望的结果。

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

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

【讨论】:

  • 你绝对是在正确的轨道上。通过您的添加,我拥有了正确的 viewModel 并获得了更新处理程序。我遇到的一个问题是更新触发了两次。第一次是未定义的,第二次是正确的值。对此有什么想法吗?
  • 我不确定我到底做错了什么,但我重新实现了您的解决方案,现在似乎工作正常。我相信我使用的是
【解决方案2】:

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

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

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

【讨论】:

  • 这两个变量都有主视图模型,而不是我的组件。有什么我没有为组件设置视图模型的事情吗?
猜你喜欢
  • 2018-05-20
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 2013-02-24
  • 1970-01-01
  • 2018-09-08
  • 2015-07-21
  • 2018-01-21
相关资源
最近更新 更多