2010-10-12 116 views
0

我不希望任何人读过这整个脚本,但您会注意到有一个带有insert()函数的排序对象,该函数返回使用三元运算符返回的对象无论是“order_value”还是“order_value”,其中order_value是一个保存值的局部变量。问题在于它总是传递“query_value”而不是“order_value”的查询字符串。我相信问题是当调用ajax方法时,它总是实例化一个新的Table对象,因此所有变量都被擦除,而不是记住-order_value,它默认返回order_value。任何解决方案查询字符串总是返回相同的值 - JavaScript

<script> 
(function($){ 

var listview = $('#listview'); 

var lists = (function(){ 
    var criteria = { 
     dropFilter: { 
      insert: function(value){ 
       if(value) 
        return {"filter" : value}; 
      }, 
      msg: "Filtering..." 
     }, 
     searchFilter: { 
      insert: function(value){ 
       if(value) 
        return {"search" : value} 
      }, 
      msg: "Searching..." 
     }, 
     sort: { 
      insert: function(order, page){ 
       arr = []; 
       arr[arr.length] = order; 
       arr[arr.length] = page; 
       return function(order_value, page_value){ 
        var order_value = (order_value.indexOf("-") > -1) ? order_value : "-" + order_value; 
        var page_value = page_value; 
        return {order : order_value, page : page_value }; 
       } 
      }, 
      msg: "Sorting..." 
     } 
    } 
    return { 
     create: function(component){ 
      var component = component.href.substring(component.href.lastIndexOf('#') + 1); 
      return component; 
     }, 
     setDefaults: function(component){ 
      var parameter = {}; 
      switch(component){ 
       case "sites": 
        parameter = { 
         'url': 'sites',       
         'order': 'site_num', 
         'per_page': '20' 
        } 
      } 
      return parameter; 
     }, 
     getCriteria: function(criterion){ 
      return criteria[criterion]; 

     }, 
     addCriteria: function(criterion, method){ 
      criteria[criterion] = method; 
     } 
    } 
})(); 

var Form = function(form){ 
    var fields = []; 
    $(form[0].elements).each(function(){ 
     var field = $(this); 
     if(typeof field.attr('alter-data') !== 'undefined') fields.push(new Field(field)); 
    }) 
} 

Form.prototype = { 
    initiate: function(){ 
     for(field in this.fields){ 
      this.fields[field].calculate(); 
     } 
    }, 
    isCalculable: function(){  
     for(field in this.fields){ 
       if(!this.fields[field].alterData){ 
       return false; 
      } 
     } 
     return true; 
    } 
} 

var Field = function(field){ 
    this.field = field; 
    this.alterData = true; 
    this.component = {'url' : window.location.hash.substring(window.location.hash.indexOf('#') + 1)}; 
    this.attach("change"); 
    this.attach("keypress"); 
} 

Field.prototype = { 
    attach: function(event){ 
     var obj = this; 
     if(event == "change"){ 
      obj.field.bind("change", function(){ 
       return obj.calculate(); 
      }) 
     } 
     if(event == "keypress"){ 
      obj.field.bind("keypress", function(e){ 
       var code = (e.keyCode ? e.keyCode : e.which); 
       if(code == 13){ 
        e.preventDefault(); 
        return obj.calculate(); 
       } 
      }) 
     } 
    }, 
    calculate: function(){ 
     var obj = this, 
      field = obj.field, 
      component = obj.component, 
      msgClass = "msgClass", 
      msgList = $(document.createElement("ul")).addClass("msgClass"), 
      types = field.attr("alter-data").split(" "), 
      container = field.parent(), 
      messages = []; 

     field.next(".msgClass").remove(); 
     for(var type in types){ 
      var criterion = lists.getCriteria(types[type]); 
      if(field.val()){ 
       var result = criterion.insert(field.val()); 

       container.addClass("waitingMsg"); 

       messages.push(criterion.msg); 

       obj.alterData = true; 

       initializeTable(component, result); 

      } 
      else { 
       return false; 

       obj.alterData = false; 
      } 
     } 
     if(messages.length){ 
      for(msg in messages){ 
       msgList.append("<li>" + messages[msg] + "</li"); 
      } 
     } 
     else{ 
      msgList.remove(); 
     } 
    } 
} 

var Table = function(table){ 
    headers = []; 
    $(table[0].getElementsByTagName('th')).each(function(){ 
     var header = $(this); 
     if(typeof header.attr('data-sorter') !== 'undefined') headers.push(new Header(header)); 
    }) 
} 

Table.prototype = { 
    isSortable: function(){ 

    } 
} 

var Header = function(header){ 

    this.header = header; 
    this.isSortable = true; 
    this.component = {'url' : window.location.hash.substring(window.location.hash.indexOf('#') + 1)}; 
    this.fieldName = header.children()[0].href.substring(header.children()[0].href.lastIndexOf("/") + 1, header.children()[0].href.length); 
    this.attach('click'); 
} 

Header.prototype = { 
    attach: function(event){ 
     var obj = this; 
     if(event == "click"){ 
      obj.header.children().bind("click", function(e){ 
       e.preventDefault(); 
       return obj.calculate(); 
      }) 
     } 
    }, 
    calculate: function(){ 
     var obj = this, 
      header = obj.header, 
      component = obj.component, 
      fieldName = obj.fieldName, //I cannot put default value here (e.g. a variable that holds -value or value, because no value will be remembered since we instantiate a new Table object at the end of this function call with initializeTable().) 
      msgClass = "msgClass", 
      msgList = $(document.createElement("ul")).addClass("msgClass"), 
      types = header.attr("data-sorter").split(" "), 
      container = header.parent(), 
      messages = []; 
      header.next(".msgClass").remove(); 

      for(var type in types){ 
       var criterion = lists.getCriteria(types[type]); 
      } 
      var result = criterion.insert("order", "page"); 
      result = result(fieldName, 1); 

      container.addClass("waitingMsg"); 
      messages.push(criterion.msg); 

      initializeTable(component, result); 
    } 
} 

$('#dashboard a').click(function(){ 
    var currentComponent = lists.create(this); 
    var defaults = lists.setDefaults(currentComponent); 
    initializeTable(defaults); 
}); 

var initializeTable = function(defaults, custom){ 

    var custom = custom || {}; 

    var query_string = $.extend(defaults, custom); 

    var params = []; 
    $.each(query_string, function(key,value){ 
     params += "&" + key + '=' + value; 
    }) 
    params = params.substring(1); 
    var url = params.substring(params.indexOf("=") + 1,params.indexOf("&")); 
    params = params.substring(params.indexOf("&")+1, params.length); 

    $.ajax({ 
     type: 'GET', 
     url: '/' + url, 
     data: params, 
     dataType: 'html', 
     error: function(){}, 
     beforeSend: function(){}, 
     complete: function() {}, 
     success: function(response) { 
      listview.html(response); 

       var form = $('form'); 
       form.calculation(); 

       var table = $('table'); 
       table.calculation(); 

     } 
    }) 


} 

$.extend($.fn, { 
    calculation: function(){ 

      switch($(this)[0].nodeName){ 
       case 'FORM': 
        var formReady = new Form($(this)); 

        if(!formReady.isCalculable){ 
         return false; 
        } 
        break; 
       case 'TABLE': 
        var tableReady = new Table($(this)) 
        if(!tableReady.isSortable){ 
         return false; 
        } 
        break; 
      } 

    } 
}) 

})(jQuery) 
</script> 

_index.html.erb:

<th data-sorter="sort"><a href="<%= (params[:order].nil?) ? :site_num : params[:order] %>">Site</a></th> 

回答

0

这里是有问题的功能。

insert: function(order, page){ 
     arr = []; 
     arr[arr.length] = order; 
     arr[arr.length] = page; 
     return function(order_value, page_value){ 
      var order_value = (order_value.indexOf("-") > -1) ? order_value : "-" + order_value; 
      var page_value = page_value; 
      return {order : order_value, page : page_value }; 
     } 
    }, 

,你会发现,线

var order_value = (order_value.indexOf("-") > -1) ? order_value : "-" + order_value; 

正在重新定义ORDER_VALUE(我觉得奇怪,不是很确定如果是这样的原因)的可能会导致编译器混淆。

由于三元运算符从未在order_value中找到符号,因此它可能指向order_value是整数的事实。

尝试把此行前行前:

alert((typeof order_value) + " : " + order_value.toString()); 
+0

它总是返回 “字符串:site_num”。这行在这里似乎是破坏记忆的变量:var tableReady = new Table($(this))因此,order_value总是等于site_num,永远不会是-site_num。所以我认为这是问题。 – JohnMerlino 2010-10-12 19:41:07

+0

实际上,应该使用params [:order]将-site_num写入erb文件中链接的href中,但它从来没有发生过。因此,当一个新表被实例化时,它会一次又一次地获取值site_num,并且永远不会等于-site_num。 – JohnMerlino 2010-10-12 19:55:53

+0

尝试这样做: var order_value1 =(order_value.indexOf(“ - ”)> -1)? order_value:“ - ”+ order_value; var page_value1 = page_value; return {order:order_value1,page:page_value1}; – 2010-10-13 02:46:08