2010-10-12 43 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

相關問題