【问题标题】:Kendo custom widget with MVVM and init event - how?带有 MVVM 和初始化事件的 Kendo 自定义小部件 - 如何?
【发布时间】:2015-10-03 12:17:07
【问题描述】:

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

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

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

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

【问题讨论】:

  • 这已经有一段时间了,但我想知道你是否解决了这个问题,因为我有同样的问题。
  • 不,我没有解决。也许应该通知 Telerik 的人。
  • 感谢您的快速响应。我浏览了他们的代码,看不到 data-init 被引用的地方。但是,有一个绑定可能同样有效。我们可以绑定到 data-bind="events: { dataBinding: onBinding, dataBinded: onBound }" 并在设置数据源时调用它,然后在完成时调用它。这恰好发生在构建 HTML 创建的小部件的过程中。希望这对你有帮助!此外,我发现它允许更改属性名称空间,从而允许它与 Knockout 一起使用。 kendo.ns="kendo-" 使 data-kendo-bind="" 工作。我会把它变成一个答案。
  • "init" 事件是我在小部件初始化时引发的自定义事件。我认为当小部件的绑定数据将被更改或被更改时,应该引发“dataBinding”和“dataBound”事件。所以我的想法是只触发一次“init”事件 - 在小部件初始化时,然后在每次更改绑定数据时选择性地触发“dataBinding”和“dataBound”事件。例如,如果我们使用 kendoDropDownList 并将“autoBind”选项设置为“false”,您将看到小部件已初始化,但在您打开下拉列表之前,不会引发“dataBound”事件。
  • 查看我的答案,因为它可以按照您的描述进行操作。

标签: events mvvm kendo-ui widget initialization


【解决方案1】:

补充:我想补充一点,我完全理解为什么还没有 init binder。这真的没有意义。由于 ViewModel 可以绑定到 Kendo 中的许多不同事物,因此在 Widget 的 Viewmodel 内的 init 回调是没有意义的。这就是使用 dataBinding 和 dataBound 的原因。创建小部件时,它会调用 data-init="" 的处理程序,它必须在范围内。这是对小部件的一次性调用。 ViewModel Observable 可以绑定和取消绑定到许多不同的小部件。系统如何知道 Observable ViewModel 应该严格绑定到那个特定的小部件?除非您将 Widget 更新为具有内部数据源且可观察,否则不会。

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

希望这会有所帮助!这无疑帮助我理解了一切。


我已经能够为所欲为。看来我对data-bind="events: {}" 的用途大错特错。该定义中的处理程序似乎是 HTML 事件的处理程序。所以我们可以向 Widget 系统本身添加一个新的“init”处理程序。我已经能够让您的示例与下面的代码一起使用。

关键是为名为“init”的剑道活动添加新的活页夹。

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 事件的。诸如可见、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>

【讨论】:

  • 好的,这听起来合乎逻辑!
猜你喜欢
  • 2013-06-03
  • 2014-09-16
  • 2013-01-10
  • 1970-01-01
  • 2019-11-13
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多