Kendo 使用 MVVM 和初始化事件的自定义小部件 - 怎么样?
Kendo custom widget with MVVM and init event - how?
我尝试使用 "Init" 事件实现自定义 kendo 小部件。如果使用 JavaScript 初始化小部件,则会触发事件。但是当使用数据属性初始化小部件时 - 它不会。我想念什么?
样本:http://dojo.telerik.com/UQoWi
注意:如您所见,我已尝试根据 KendoUI 的文档处理 "init" 事件:
... data-init="onInit" data-bind="events: { init: onInit }" ...
补充:我想补充一点,我完全理解为什么还没有 init 活页夹。这真的没有意义。由于 ViewModel 可以绑定到 Kendo 中的许多不同事物,因此在 Viewmodel 中为 Widget 进行初始化回调是没有意义的。这就是使用 dataBinding 和 dataBound 的原因。创建小部件时,它会调用 data-init="" 的处理程序,它只需要在范围内即可。这是对小部件的一次性调用。 ViewModel Observable 可以绑定和解除绑定到许多不同的小部件。系统如何知道 Observable ViewModel 应该严格绑定到那个特定的小部件?除非您更新小部件以具有内部数据源和可观察性,否则不会。
如果此 Observable 绑定到您的多个自定义小部件,则将为每个小部件调用 onInit。它不会被任何内置小部件调用,因为它们不会触发(INIT)。这很容易通过重载 fn.init 函数或扩展它们来解决。或者,甚至创建一个在 data-init
元素属性中使用的全局 onInit 函数,因为您可以通过参数访问小部件本身。 $(element).data("kendoWidget")
等等
希望这对您有所帮助!它确实帮助我理解了一切。
我已经能够做你想做的事了。看来我对 data-bind="events: {}"
的用途有很大的误解。该定义中的处理程序似乎是 HTML 事件的处理程序。所以我们可以向 Widget 系统本身添加一个新的 'init' 处理程序。我已经能够让您的示例使用下面的代码。
关键是为名为 'init' 的 Kendo 事件添加一个新的活页夹。
kendo.data.binders.widget.init =
kendo.data.Binder.extend({
function(widget, bindings, options) {
Binder.fn.init.call(this, widget.element[0], bindings, options);
this.widget = widget;
},
refresh: function () {
var init = this.bindings.init.get();
}
});
然后我们可以使用 data-bind="init: onInitFromMVVM"
绑定到一次性偶数调用。这只会是一次性调用,因为它只会在 Widget 的初始化中触发。
我一遍又一遍地浏览源代码,events: {}
让我感到困惑,直到我开始阅读文档。然后我意识到 events: {}
中的几乎所有处理程序都是针对 HTML 事件的。诸如 visible、onmouseover、onmouseexit 等之类的东西。然后我创建了一个名为 'init' 的新活页夹,之后您的代码就可以正常工作了。
下面的代码产生以下输出:
widget init proof
global init proof
init mvvm proof
它甚至在全局范围内调用 data-init
的处理程序。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/kendo.all.min.js"></script>
<script>
var binders = kendo.data.binders,
Binder = kendo.data.Binder,
proxy = $.proxy,
ui = kendo.ui,
Widget = ui.Widget,
INIT = 'init';
(function ($) {
kendo.data.binders.widget.init =
kendo.data.Binder.extend({
init: function(widget, bindings, options) {
Binder.fn.init.call(this, widget.element[0], bindings, options);
this.widget = widget;
},
refresh: function () {
var init = this.bindings.init.get();
}
});
var MyWidget = Widget.extend({
options: {
name: 'MyWidget',
},
events: [
INIT
],
init: function (element, options) {
var that = this;
console.log('widget init proof');
Widget.fn.init.call(this, element, options);
that.trigger(INIT);
}
});
ui.plugin(MyWidget);
})(jQuery);
$(document).ready(function () {
var observableModel = new kendo.data.ObservableObject({
onInitVM: function (e, opts) {
console.log('init mvvm proof');
}
});
kendo.bind($('#myWidgetMVVM'), observableModel);
});
</script>
</head>
<body>
<div>Open console...</div>
<input type="hidden" id="myWidgetMVVM" data-init="onInit" data-role="mywidget" data-bind="init: onInitVM" />
<script>
function onInit(element, options) {
console.log("global init proof");
}
</script>
</body>
</html>
我尝试使用 "Init" 事件实现自定义 kendo 小部件。如果使用 JavaScript 初始化小部件,则会触发事件。但是当使用数据属性初始化小部件时 - 它不会。我想念什么?
样本:http://dojo.telerik.com/UQoWi
注意:如您所见,我已尝试根据 KendoUI 的文档处理 "init" 事件:
... data-init="onInit" data-bind="events: { init: onInit }" ...
补充:我想补充一点,我完全理解为什么还没有 init 活页夹。这真的没有意义。由于 ViewModel 可以绑定到 Kendo 中的许多不同事物,因此在 Viewmodel 中为 Widget 进行初始化回调是没有意义的。这就是使用 dataBinding 和 dataBound 的原因。创建小部件时,它会调用 data-init="" 的处理程序,它只需要在范围内即可。这是对小部件的一次性调用。 ViewModel Observable 可以绑定和解除绑定到许多不同的小部件。系统如何知道 Observable ViewModel 应该严格绑定到那个特定的小部件?除非您更新小部件以具有内部数据源和可观察性,否则不会。
如果此 Observable 绑定到您的多个自定义小部件,则将为每个小部件调用 onInit。它不会被任何内置小部件调用,因为它们不会触发(INIT)。这很容易通过重载 fn.init 函数或扩展它们来解决。或者,甚至创建一个在 data-init
元素属性中使用的全局 onInit 函数,因为您可以通过参数访问小部件本身。 $(element).data("kendoWidget")
等等
希望这对您有所帮助!它确实帮助我理解了一切。
我已经能够做你想做的事了。看来我对 data-bind="events: {}"
的用途有很大的误解。该定义中的处理程序似乎是 HTML 事件的处理程序。所以我们可以向 Widget 系统本身添加一个新的 'init' 处理程序。我已经能够让您的示例使用下面的代码。
关键是为名为 'init' 的 Kendo 事件添加一个新的活页夹。
kendo.data.binders.widget.init =
kendo.data.Binder.extend({
function(widget, bindings, options) {
Binder.fn.init.call(this, widget.element[0], bindings, options);
this.widget = widget;
},
refresh: function () {
var init = this.bindings.init.get();
}
});
然后我们可以使用 data-bind="init: onInitFromMVVM"
绑定到一次性偶数调用。这只会是一次性调用,因为它只会在 Widget 的初始化中触发。
我一遍又一遍地浏览源代码,events: {}
让我感到困惑,直到我开始阅读文档。然后我意识到 events: {}
中的几乎所有处理程序都是针对 HTML 事件的。诸如 visible、onmouseover、onmouseexit 等之类的东西。然后我创建了一个名为 'init' 的新活页夹,之后您的代码就可以正常工作了。
下面的代码产生以下输出:
widget init proof
global init proof
init mvvm proof
它甚至在全局范围内调用 data-init
的处理程序。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/kendo.all.min.js"></script>
<script>
var binders = kendo.data.binders,
Binder = kendo.data.Binder,
proxy = $.proxy,
ui = kendo.ui,
Widget = ui.Widget,
INIT = 'init';
(function ($) {
kendo.data.binders.widget.init =
kendo.data.Binder.extend({
init: function(widget, bindings, options) {
Binder.fn.init.call(this, widget.element[0], bindings, options);
this.widget = widget;
},
refresh: function () {
var init = this.bindings.init.get();
}
});
var MyWidget = Widget.extend({
options: {
name: 'MyWidget',
},
events: [
INIT
],
init: function (element, options) {
var that = this;
console.log('widget init proof');
Widget.fn.init.call(this, element, options);
that.trigger(INIT);
}
});
ui.plugin(MyWidget);
})(jQuery);
$(document).ready(function () {
var observableModel = new kendo.data.ObservableObject({
onInitVM: function (e, opts) {
console.log('init mvvm proof');
}
});
kendo.bind($('#myWidgetMVVM'), observableModel);
});
</script>
</head>
<body>
<div>Open console...</div>
<input type="hidden" id="myWidgetMVVM" data-init="onInit" data-role="mywidget" data-bind="init: onInitVM" />
<script>
function onInit(element, options) {
console.log("global init proof");
}
</script>
</body>
</html>