【问题标题】:What is best way to bind a Kendo UI dropdownlist to a ViewModel that is populated by a datasource?将 Kendo UI 下拉列表绑定到由数据源填充的 ViewModel 的最佳方法是什么?
【发布时间】:2014-02-13 03:29:14
【问题描述】:

我有一个 kendoUI 下拉列表,它位于模板中并绑定到 ViewModel,以及绑定到下拉列表中选择的数据项的跨度:

<p>
    <label>Appointment Type: </label>
    <select id="appointmentTypeDropDownList"
            data-text-field="Name"
            data-value-field="AppointmentTypeId"
            data-role="dropdownlist"
            data-bind="source:appointmentTypes, value:AppointmentTypeId"
            data-autobind="true"
            data-select="onSelected" />
</p>
<p><label>Duration:</label>
    <span data-bind="text:selectedAppointment.Duration"></span> minutes
</p>

我的视图模型:

var viewModel = new kendo.observable({
    appointmentTypes: appointmentTypesDataSource,
    selectedAppointment : null,
});

最初,我使用硬编码的约会类型数组,并在上面的 viewModel 声明中将 selectedAppointment 设置为约会类型 [0]。这现在不起作用,因为数据源是异步加载的。 viewModel 在 onSelected 函数中更新:

var onSelected = function (e) {
    var dataItem = this.dataItem(e.item.index());
    viewModel.set("selectedAppointment", dataItem);
};

模板在一个窗口中,第一次加载时 span 是空的,然后再工作(一旦从第一个请求加载数据)。

我的问题是,如何让 span 的数据绑定在第一个请求上工作,以便它显示数据源返回的列表中当前选择的约会类型的持续时间?我是否尝试将其绑定到下拉列表的选定数据项?我应该在某个地方使用回调来执行此操作吗?如果重要的话,模板在 kendoScheduler 中:

var template = kendo.template($("#editor").html());

$("#scheduler").kendoScheduler({
    editable: {
        template: template()
    }
});

谢谢!

更新:我一直在使用的模板是 Kendo UI Scheduler 的编辑器,它没有绑定到它的视图模型,而是将视图模型的一部分用于它的数据源。在这种情况下,尝试使用 data-bind="events:{...}" 语法会导致我遇到奇怪的类型错误。为了连接数据绑定事件,Atanas 让我知道使用 data-bound="onDataBound" 和全局处理程序函数(或者以声明方式配置我的调度程序并将其绑定到视图模型)。结合使用数据绑定和下面的答案对我有用。

【问题讨论】:

  • selectedAppointment 的初始值是多少?你如何从数据源中确定它?显然你不希望它为空。
  • 它应该匹配下拉列表中的第一项,因为如果用户只保存表单,下拉列表中的第一项将是选定的值。

标签: javascript kendo-ui kendo-mvvm kendo-datasource


【解决方案1】:

您可以使用下拉列表中的dataBound 事件并从那里设置selectedAppointment

data-bind="source:appointmentTypes, value:AppointmentTypeId, events: { dataBound: onDataBound }"

和你的视图模型:

var viewModel = new kendo.observable({
    appointmentTypes: appointmentTypesDataSource,
    selectedAppointment : null,
    onDataBound: function(e) {
        e.sender.select(0); // will trigger your change handler
    }
});

【讨论】:

  • 试图让它工作但得到错误“未捕获的类型错误:未定义不是函数”,这似乎发生在声明性初始化中。我已经在我的 viewModel 上使用 onDataBound 进行了尝试,如图所示并作为全局变量;同样的效果。有任何想法吗?谢谢。
  • 还有,为什么我可以对选择事件使用数据选择,而对数据绑定事件却不能使用数据数据绑定?
  • 此 jsFiddle 暗示数据绑定绑定不适用于 DropDownList 小部件:jsfiddle.net/7GE3b/1
  • 我设置了一个demo here;您的 jsfiddle 可能无法正常工作,因为它使用的是相当旧版本的 kendo ui;关于您的问题:如果要将视图模型上的方法绑定到事件,则需要在数据绑定中进行(如果您使用数据选择进行设置,它只会在全局范围内查找函数)
  • @Julie 我一直在和我的电脑争论“我的意图很明显!当然,你一定知道我的意思吗?”;但他总是对我嗤之以鼻,并抛出异常和其他下流话。有时我想知道他是否真的把我当回事。
【解决方案2】:

您需要设置 selectedAppointment 的初始值。这是在填充数据源之前设置跨度文本的唯一方法。这是一个基于 Northwind 产品的可运行演示:

<span data-bind="text:selectedProduct.ProductName"></span>
<select data-bind="source: products, value: selectedProduct"
      data-text-field="ProductName"
      data-value-field="ProductID"
      data-role="dropdownlist"></select>
<script>
var o = kendo.observable({
  selectedProduct: {
    ProductID: 2,
    ProductName: "Chang"
  },
  products: new kendo.data.DataSource({
    transport: {
      read: {
        url: "http://demos.telerik.com/kendo-ui/service/products",
        dataType: "jsonp"
      }
    }
  })
});

kendo.bind(document.body, o);
</script>

这是一个现场演示:http://jsbin.com/pawiz/1/edit

【讨论】:

  • Lars 展示的这个例子怎么样:plnkr.co/edit/kpQzzY9xWLxpt5aOlRj3?p=preview?我无法让它在我的实际代码中工作,因为我总是在我的 events:{} 绑定中收到“Uncaught TypeError: undefined is not a function”错误,但它在他的演示中显然有效。我可以让它与您的代码一起使用,但这显然是一个 hack,因为我现在必须在我的客户端脚本中嵌入魔法值,而不是依赖数据源中的实际数据。谢谢!
  • 为什么这显然是一个 hack?在你的真实场景中,“价值”来自哪里?它不是其他东西的属性吗?数据源本身不支持“选定值” - 它仅表示项目数组。一旦收到数据,链接的示例总是选择第一个数据项。
  • 由于下拉列表没有空的第一项(例如“选择一项”),因此无论第一项是什么,都是默认项。按照同样的约定,无论下拉列表的数据源中的第一项是什么,都应该是视图模型中的默认 selectedItem(在我的例子中,它的 Duration 属性显示在绑定跨度中)。在客户端代码中包含来自数据源的名称/ID 是一种技巧,因为我将来可能会更改数据源,或者该数据的顺序可能会更改,除非我更新硬编码值,否则我的代码将不正确。
  • 在您的示例中,如果有人添加了在“Chang”之前列出的新产品,假设是“Asparagus”。现在,span 将显示“Chang”,但下拉列表中的第一项将显示“Asparagus”,对吧?
  • 没有。两者都将保持不变-Chang。除非新项目与 Chang 具有相同的 ProductID。无论如何,如果您不想设置初始值,则必须像 Lars 那样做。不知何故触发下拉列表的变化:jsbin.com/pawiz/2/edit
猜你喜欢
  • 2011-04-07
  • 1970-01-01
  • 2019-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 1970-01-01
  • 2015-08-16
相关资源
最近更新 更多