使用MVVM和init事件的Kendo自定义小部件 - 如何?

时间:2015-10-03 12:17:08

标签: events mvvm kendo-ui widget initialization

我尝试使用“Init”事件实现自定义kendo小部件。如果使用JavaScript初始化窗口小部件,则会触发该事件。但是当使用数据属性初始化窗口小部件时 - 它不会。我错过了什么?

示例:http://dojo.telerik.com/UQoWi

注意:正如您所看到的,我已尝试根据KendoUI的文档处理“init”事件:

... data-init="onInit" data-bind="events: { init: onInit }" ...

1 个答案:

答案 0 :(得分:1)

补充:我想补充一点,我完全理解为什么没有init绑定器。它没有任何意义。由于ViewModel可以绑定到Kendo中的许多不同的东西,因此在Widget的Viewmodel中进行初始化回调是没有意义的。这就是使用dataBinding和dataBound的原因。创建窗口小部件时,它会调用data-init =""的处理程序,它只需要在范围内。这是对小部件的一次性调用。 ViewModel Observable可以绑定和解绑到许多不同的小部件。系统如何知道Observable ViewModel应该严格依赖于那个特定的小部件?除非您更新Widget以获得内部数据源并且可观察,否则它不会。

如果此Observable绑定到多个自定义小部件,则将为每个小部件调用onInit。它不会被调用任何内置小部件,因为它们不会触发(INIT)。通过重载fn.init函数或扩展它们可以很容易地解决这个问题。或者,甚至创建在data-init元素属性中使用的全局onInit函数,因为您可以通过参数访问窗口小部件本身。 $(element).data("kendoWidget")等。

希望这有帮助!它确实帮助我理解了一切。

我能够做你想做的事。似乎我对data-bind="events: {}"的含义大错特错。该定义中的处理程序似乎是HTML事件的处理程序。所以我们可以添加一个新的' init' Widget系统本身的处理程序。我已经能够让您的示例使用以下代码。

关键是为名为' 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的init中触发。

我一遍又一遍地浏览了源代码,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>