如果绑定,KnockoutJS中的jqDialog

时间:2014-04-29 08:57:07

标签: javascript knockout.js

如果绑定(" Tabs")里面有jqDialogs。在我转到另一个选项卡而不是后退之后,它会导致初始化jqDialogs并创建一个新的实例=>所以我有2个或更多(取决于从选项卡到选项卡的跳转次数)相同的对话框而不是一个。 谢谢!

<!-- ko if: IsTabVisible-->
     <div data-bind="jqDialog:{buttons:[{ text: '@Resources.Resource.Save',
    click: Save},{ text: '@Resources.Resource.Cancel',
    click: UndoChanges}], modal: true, autoOpen: false,
    close: UndoChanges, title: "title"},
    dialogVisible: Isvisible, jqButton:{
    index: 0, disabled: HasError}">
    //some content
    </div>
 <!-- /ko -->
ko.bindingHandlers.jqDialog = {
         modifyDialog: function (e) {
         if (ko.isWriteableObservable(e.data.prop)) {
         e.data.prop(e.data.state);
        }
        else {
          e.data.el.dialog(e.data.state === true ? "open" : "close");
        }
      },
      functionMouseHover: function (e) {
        if (!e.data.state) {
          if (e.data.el.data('timeoutId') == null) {
            var timeoutId = setTimeout(function () {
              ko.bindingHandlers.jqDialog.modifyDialog(e);
              e.data.el.data('timeoutId', null);
            }, 650);

            e.data.el.data('timeoutId', timeoutId);
          }
        }
        else {
          if (e.data.el.data('timeoutId') != null) {
            clearTimeout(e.data.el.data('timeoutId'));
            e.data.el.data('timeoutId', null);
          }
          ko.bindingHandlers.jqDialog.modifyDialog(e);
        }
      },
      init: function (element, valueAccessor, allBindingsAccessor) {
        var options = ko.utils.unwrapObservable(valueAccessor()) || {},
                    mouseOverElement = ko.utils.unwrapObservable(allBindingsAccessor().mouseOverElement)
        $el = $(element);
        //do in a setTimeout, so the applyBindings doesn't bind twice from element being copied and moved to bottom
        setTimeout(function () {
          var dialog = $(element).dialog(options);
          var functionMouseHover = null;

          if (mouseOverElement != null) {
            $(mouseOverElement).mouseenter({ state: true, el: $el, prop: allBindingsAccessor().dialogVisible }, ko.bindingHandlers.jqDialog.functionMouseHover).
                                                        mouseleave({ state: false, el: $el, prop: allBindingsAccessor().dialogVisible }, ko.bindingHandlers.jqDialog.functionMouseHover);

            dialog.mouseenter({ state: true, el: $el, prop: allBindingsAccessor().dialogVisible }, ko.bindingHandlers.jqDialog.functionMouseHover).
                                                        mouseleave({ state: false, el: $el, prop: allBindingsAccessor().dialogVisible }, ko.bindingHandlers.jqDialog.functionMouseHover);
          }
        }, 0);
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
          $(element).dialog("destroy");
        });
      },
      update: function (element, valueAccessor, allBindingsAccessor) {
        var shouldBeOpen = ko.utils.unwrapObservable(allBindingsAccessor().dialogVisible),
                    hideTitelBar = ko.utils.unwrapObservable(allBindingsAccessor().hideTitelBar),
                    mouseOverElement = ko.utils.unwrapObservable(allBindingsAccessor().mouseOverElement),
            $el = $(element),
                                    dialog = $el.data("uiDialog") || $el.data("dialog");
        var options = valueAccessor();

        //don't call open/close before initilization
        if (dialog) {
          var isOpen = $el.dialog("isOpen");
          $el.dialog(shouldBeOpen === true ? "open" : "close");

          if (hideTitelBar === true) {
            $el.dialog('widget').find(".ui-dialog-titlebar").hide();
          } else if (hideTitelBar === false) {
            $el.dialog('widget').find(".ui-dialog-titlebar").show();
          }

          for (var key in options) {
            if (ko.isObservable(options[key])) {
              $el.dialog("option", key, options[key]());
            }
          }

          if (options.title != undefined) {
            $el.dialog({ title: options.title });
          }

          if (shouldBeOpen === true && !isOpen) {
            $("input").blur();
          }
          if ($Render != null && shouldBeOpen) {
            $Render.renderUpdate();
          }
          if (options['type']) {
            if (options['type'] == 'warning') {
              $el.dialog("option", "width", 400);
              $el.dialog("option", "height", 'auto');
              $el.dialog("option", "position", "center");
            }

            else if (options['type'] == 'bookmarks') {
              $el.dialog("option", "width", 250);
              $el.dialog("option", "minHeight", 100);
            }
            else if (options['type'] == 'mediumDialog') {
              $el.dialog("option", "width", $(window).innerWidth() * 0.6);
              $el.dialog("option", "height", $(window).innerHeight() * 0.4);
              $el.dialog("option", "position", "center");
            }
          }
          else {
            $el.dialog("option", "width", $(window).innerWidth() * 0.8);
            $el.dialog("option", "height", $(window).innerHeight() * 0.8);
            $el.dialog("option", "position", "center");
          }
        }
        else {
          if (ko.isWriteableObservable(allBindingsAccessor().dialogVisible)) {
            allBindingsAccessor().dialogVisible(false);
          }
        }
      }
    };

1 个答案:

答案 0 :(得分:0)

您可能希望使用visible绑定。请注意if绑定上的documentation

  

如果扮演与可见绑定类似的角色。不同的是   可见,包含的标记始终保留在DOM中   始终应用其数据绑定属性 - 仅可见绑定   使用CSS来切换容器元素的可见性。 if绑定,   但是,在DOM中物理添加或删除包含的标记,   并且只有在表达式为真时才对后代应用绑定。

所以你的div每次都被移除并重新添加 - 导致一次又一次地处理init绑定。