jQuery UI的小部件“destroy”方法 - 不一致的错误

时间:2016-01-13 20:10:59

标签: javascript jquery jquery-ui

哇,我在StackOverflow上的第一个问题!

对于那里的jQuery UI大师,我坚持这个,这需要很多。我已经阅读了所有的api文档,并且一直空着。

所以,这个例子非常简单,不用担心为什么我这样做,我只是想在一个小部件上调用jQuery UI的.destroy()方法中的简单不一致的解释

在我的第一个示例中,我在datepicker小部件上调用destroy方法,然后将该元素重新初始化为datepicker小部件。正如我所料,这是有效的。由于datepicker当前不存在,因此忽略destroy方法并创建datepicker小部件。

$("#datepicker").datepicker("destroy").datepicker();

在我的第二个例子中,我这次选择了另一个小部件,一个按钮。我尝试的方法与我的第一个例子相同,除了这次,我收到一个错误,错误:在初始化之前无法调用按钮上的方法;试图调用方法'destroy'

$("#button").button("destroy").button();

那么,这是怎样以及为什么会发生这种情况?文档读取两个小部件datepicker的完全相同的方式; button。我觉得奇怪的是它只会以这种方式实现一个datepicker小部件而不是所有其他本机jQuery UI小部件。

万一有人好奇,我可以在Chrome 47.0.2526.106 m& D中重现相同的结果。 IE 11.0.9600.18097(更新11.0.25)

另外,为了方便你,这里有一个工作代码片段,它显示了两个例子,第一个是工作,第二个是抛出元素下面显示的错误。为了探索所有选项,我继续使用对话框小部件在代码段中添加了第三个示例,并收到相同的错误。

(function ($){
  try {
    $("#datepicker").datepicker("destroy").datepicker();
  }
  catch (e) {
    $("#datepickerError").html(e);
  }
  
  try {
    $("#button").button("destroy").button();
  }
  catch (e) {
    $("#buttonError").html(e);
  }
  
  try {
    $("#dialog").dialog("destroy").dialog(); 
  }
  catch (e) {
    $("#dialogError").html(e);
  }
})(window.jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>


<input type="text" id="datepicker" />
<br />
<span id="datepickerError">(no error)</span>
<br /><br />
<input type="button" id="button" value="Button" />
<br />
<span id="buttonError">(no error)</span>
<br />
<br />
<div id="dialog" title="test"></div>
<br />
<span id="dialogError">(no error)</span>

1 个答案:

答案 0 :(得分:1)

我相信这是因为DatePicker不是真正的jquery小部件,因为它不像其他小部件一样使用小部件工厂。它使用$.fn原型来定义自己。从代码中它来创建日期选择器方法

$.fn.datepicker = function(options){

当widget工厂小部件向小部件工厂注册时,工厂处理创建方法:

$.widget( "ui.button", { .... });

事实上,我相信它仍然在使用widget工厂重写它的路径。

http://wiki.jqueryui.com/w/page/12137778/Datepicker

  

我们要在此处解决的具体代码和功能更改   重构是:

     

重构代码以使用小部件工厂并关注   jQuery UI API

小部件工厂是处理所有小部件魔法的东西,其中一个是查找小部件已被调用的元素实例,并确定它是否已被实例化并显示该错误。但是由于DatePicker不使用小部件工厂,它可能不会因为小部件工厂错误而失败,并且很可能正常失败,因为大多数jquery的东西在你正在操作的jquery对象中没有元素时会这样做。

事实上,如果您取消选择jquery ui下载中的所有内容,只选择DatePicker及其所需的任何依赖项。查看下载的文件。甚至不包括窗口小部件工厂,也是错误消息。现在在UI Core下检查小部件并再次下载。再次搜索该错误消息。它就是!在$.widget.bridge函数下。

if ( !instance ) {
    return $.error( "cannot call methods on " + name + " prior to initialization; " + 
    "attempted to call method '" + options + "'" );
}

如果我们查看日期选择器代码,您可以在传递选项时看到它,它会尝试在某些情况下构建方法名称。其中一个是_destroyDatepicker$.fn扩展函数中没有代码可以阻止它在没有使用datePicker实例化元素时调用任何东西,因此它构建了该函数名并调用了函数,并且destroy中的前几行之一是

if (!$target.hasClass(this.markerClassName)) {
    return;
}

所以这很可能就是在没有任何错误的情况下纾困的地方。

简而言之,你是对的。这是不一致的。有一个原因,但除非你熟悉他们的代码,否则它根本不是显而易见的。