剑道淘汰赛:窗口无法正确关闭(Kendo-Knockout: Window does not clo

2019-10-17 12:20发布

我使用RPNiemeyer剑道淘汰赛库。 我有一个网格。 当用户点击网格中的行显示一个弹出窗口。 当你以同样的方式关闭该窗口并打开它再次申请冻结与关闭动画。 我试着尽我所能来重现这一场景小提琴。 在拨弄当您关闭弹出窗口,点击该行又什么都不会发生,而浏览器重新加载。 我坚信,类似的事情在我的应用程序正在发生的事情。

HTML:

<div data-viewId="languageList" >
    <div id="languageList" data-bind="with: viewModel">
        <div id="languageListGrid" data-bind="kendoGrid: { data: languageViewModels, columns: [ 
                { 
                    template: '<a href=\'\' data-bind=\'click: function() { onLanguageSelected(&quot;#=Language#&quot;) }\'>#=Language#</a>', 
                    field: 'Language', 
                    title: 'Language',
                    width: 50
                }

                ], 
            scrollable: false, sortable: true, pageable: false }" style="height: 380px">

        </div>
    </div>
</div>

<div data-viewid="languageDetails">
    <div id="languageDetails" data-bind="with: viewModel" class="hidden">
        <form id="languageDetailsForm" action="" style="font-family: Trebuchet MS, Verdana, Helvetica, Sans-Serif;">
        <div data-bind="kendoWindow: {isOpen: isOpen, title:'Language', width: 400, height: 200, modal: true }" >
            test
            <button id="cancelLanguage" class="k-button" data-bind="click: cancelLanguage">Cancel</button>
        </div>
       </form>
    </div>
</div>​

JavaScript的:

$(function () {

    var elementIsBoundNew = function (element) {
        return !!ko.dataFor(element);
    }

    var applyBindings = function (viewModel, elementId) {
        var element = $('div[data-viewId="' + elementId + '"]')[0];
        if (!elementIsBoundNew(element)) {
            var parentViewModel = { viewModel: viewModel };
            ko.applyBindings(parentViewModel, element);
        }
    };

    var FranchiseDetailsViewModel = function () {
        var 
            self = this,
            initialize = function () {
                self.languagesInfoViewModel(new LanguageListViewModel(self));
                applyBindings(self.languagesInfoViewModel, "languageList");
            };

        FranchiseDetailsViewModel.prototype.languagesInfoViewModel = ko.observable();
        initialize();
    };

    var LanguageListViewModel = function (franchise) {
        var 
            self = this,
            initialize = function () {
                var languageViewModel = new LanguageDetailsViewModel(franchise);
                self.languageViewModels.push(languageViewModel);
            };
        LanguageListViewModel.prototype.languageViewModels = ko.observableArray([]);
        LanguageListViewModel.prototype.selectedLanguageViewModel = ko.observable();

        LanguageListViewModel.prototype.onLanguageSelected = function (selectedLanguage) {
  // when you uncomment this line everyting works fine
  //var language = new LanguageDetailsViewModel();  
            self.selectedLanguageViewModel(self.languageViewModels()[0]);

            applyBindings(self.selectedLanguageViewModel, "languageDetails");

            self.selectedLanguageViewModel().openPopUp();
        };
        initialize();
    };

    var LanguageDetailsViewModel = function () {
        var 
            self = this,
            closePopUp = function () {
                self.isOpen(false);
            };

        self.Language = ko.observable("English");

        LanguageDetailsViewModel.prototype.isOpen = ko.observable(false);

        LanguageDetailsViewModel.prototype.openPopUp = function () {
            self.isOpen(true);
        };

        LanguageDetailsViewModel.prototype.cancelLanguage = function () {
            closePopUp();
        };

    };

    var initialize = new FranchiseDetailsViewModel();
});​

奇怪的是,如果我这一行的代码添加到我的onLanguageSelected方法everyting正常工作:

var language = new LanguageDetailsViewModel();

小提琴:

http://jsfiddle.net/bZF9k/26/

与工作示例任何帮助,将不胜感激。 谢谢!

每RPNiemeyer`s后更新:

我已经添加几行代码使用从这里的技术剑道淘汰赛:调用了从与网格内的数据绑定模板改变视图模型性能的方法,打破绑定 :

 ko.bindingHandlers.preventBinding = {
      init: function() {
          return { controlsDescendantBindings: true };
      }        
    };

    ko.bindingHandlers.kendoGrid.options.dataBound = function(data) {
      var body = this.element.find("tbody")[0];

      if (body) {
         ko.applyBindings(ko.dataFor(body), body);   
      }
    };

这究竟是什么在我的应用程序发生。 当我打开弹出,关闭它比再次打开它没有正确关闭的第二次。 请参阅我的更新小提琴:

http://jsfiddle.net/bZF9k/29/

我在想什么? 再次感谢您的反馈!

Answer 1:

它看起来像窗口不正确地清理关闭后。 这通常不是一个问题(希望),但如果网格进行重新渲染,然后一个新的kendoWindow被初始化,不知道,有一个窗口已经在那里。

有可能在淘汰赛中,剑道代码来处理这个问题。 在destroy窗口的方法已经被调用,所以我需要看看它为什么没有真正删除的窗口元素。

一种用于现在的解决方法是配置时,窗口被关闭像一个全球性的处理程序:

  ko.bindingHandlers.kendoWindow.options.close = function() {
      $('.k-window, .k-overlay').remove();
  };

样品在这里: http://jsfiddle.net/rniemeyer/dcYRM/



Answer 2:

这是淘汰赛,剑道的错误。

destroy窗口的方法不叫。 这是因为,敲除剑术被检测到一个小部件需要当它从DOM除去被破坏。 然而, kendoWindow移动元件到DOM的末尾。 当knockout.js清除或在更新过程中移除的元件,它不删除元件,由于元件已被移动。

这可以通过修改敲除剑术以便就位代理元件,其中创建该元件后面叶被固定kendoWindow是,和destroy荷兰国际集团的kendoWindow代理元件设置时插件。 以下更改淘汰赛剑道0.7.0做到这一点:

--- knockout-kendo-0.7.0.js 
+++ knockout-kendo-0.7.0.js
@@ -62,14 +62,19 @@
                   return { controlsDescendantBindings: true };
               }
         };

         //build the core logic for the init function
         binding.setup = function(element, options, context) {
-            var widget, $element = $(element);
+            var widget, $element = $(element), $disposeProxy;

+            // Create proxy in original location to capture when the element would have been disposed
+            if (widgetConfig.destroyByProxy) {
+                $disposeProxy = $('<div style="display: none" />').insertAfter($element);
+            }
+            
             //step 2: setup templates
             self.setupTemplates(widgetConfig.templates, options, element, context);

             //step 3: initialize widget
             widget = self.getWidget(widgetConfig, options, $element);

@@ -78,12 +83,17 @@

             //step 5: set up computed observables to update the widget when observable model values change
             self.watchValues(widget, options, widgetConfig, element);

             //step 6: handle disposal, if there is a destroy method on the widget
             if(widget.destroy) {
+                if ($disposeProxy) {
+                    ko.utils.domNodeDisposal.addDisposeCallback($disposeProxy[0], function() {
+                        widget.destroy();
+                    });
+                }
                 ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
                     widget.destroy();
                 });
             }
         };

@@ -768,13 +778,16 @@
         }
     },
     watch: {
         content: CONTENT,
         title: TITLE,
         isOpen: [OPEN, CLOSE]
-    }
+    },
+    // The dom element that contains the window isn't going to be disposed when the template containing it is rendered again.
+    // This is because the window's dom element is placed at the end of the document structure by kendoWindow
+    destroyByProxy: true
 });

 createBinding({
     name: "kendoChart",
     watch: {
         data: function(value) {


文章来源: Kendo-Knockout: Window does not close correctly