2011年11月27日 星期日

前端處理JSON資料 - 轉為陣列以及簡單篩選


寫ASP.NET MVC的時候,前端與後端的資料處理上常常都會使用到JSON格式的資料,

頁面上的資料呈現與處理都可以直接使用前端程式來執行,而後端就只需要去做產出資料與接收資料的工作,

而前端程式中要去處理JSON資料時,我比較常用的就是把它轉為物件陣列然後再做進階的處理,

以下就簡單記錄一下這些處理的操作方式。


後端ASP.NET MVC程式

我在之前有針對後端產生JSON資料的方式有寫過幾篇文章,所以這邊我就不多做說明,

而我這邊用了兩種簡單的方式來產生JSON資料,一個是使用基本的JsonResult以及使用JSON.NET的處理方式,

JsonResult

這邊我使用的是Dictionary<string, object>的容器來裝載資料,最後再由程式去序列化為JSON格式的資料傳到前端。

[HttpPost]
public JsonResult GetProductsJSONResult()
{
  ProductService service = new ProductService();
  var data = service.FetchAll();
  List<Dictionary<string, object>> ja = new List<Dictionary<string, object>>();
  foreach (var item in data)
  {
    Dictionary<string, object> jo = new Dictionary<string, object>();
    jo.Add("ProductID", item.ProductID);
    jo.Add("ProductName", item.ProductName);
    jo.Add("CategoryID", item.CategoryID);
    jo.Add("CategoryName", item.Category.CategoryName);
    jo.Add("SupplierID", item.SupplierID);
    jo.Add("CompanyName", item.Supplier.CompanyName);
    ja.Add(jo);
  }
  return Json(ja);
}

 

ActionResult + JSON.NET

這裡就是使用JSON.NET所提供的JArray與JObject來裝載資料,最後再使用JsonConvert.SerializeObject做序列化為JSON的處理,

為了要讓回傳得標頭可以被正確讀取為JSON格式,所以 ContentType 就明顯指定為「application/json」

public ActionResult GetProducts()
{
  ProductService service = new ProductService();
  var data = service.FetchAll();
      
  JArray ja = new JArray();
  foreach (var item in data)
  {
    JObject jo = new JObject();
    jo.Add("ProductID", item.ProductID);
    jo.Add("ProductName", item.ProductName);
    jo.Add("CategoryID", item.CategoryID);
    jo.Add("CategoryName", item.Category.CategoryName);
    jo.Add("SupplierID", item.SupplierID);
    jo.Add("CompanyName", item.Supplier.CompanyName);
    ja.Add(jo);
  }
  return Content(JsonConvert.SerializeObject(ja), "application/json");
}

 

以上兩種後端產生JSON資料的程式雖有不同,但是產出的資料結果是一樣的,

至於使用上要使用哪一種?其實也沒有說哪種比較好,就看自己比較習慣那一種就用哪一種吧…

產出結果:

image

image

image

 

前端程式中,將JSON資料轉為Array

function GetData(actionUrl)
{
  var result = new Array();
  $.ajax(
  {
    url: actionUrl,
    type: 'post',
    cache: false,
    async: false,
    dataType: 'json',
    success: function(data)
    {
      if(data)
      {
        $.each(data, function(i, item)
        {
          var inner = 
          {
            ProductID : item.ProductID,
            ProductName : item.ProductName,
            CategoryID : item.CategoryID,
            CategoryName : item.CategoryName,
            SupplierID : item.SupplierID,
            CompanyName : item.CompanyName,
          }
          result.push(inner);
        });
      }
    }
  });
      
  return result;
}

這邊我是用jQuery的$.Ajax()去向後端取得JSON資料來源,當取到資料後就使用了$.each()以及 push() 方法,

$.each() 是去逐一遍歷JSON資料,將一筆筆的JSON資料置入到一個物件之中,

一個物件建立好並置入欄位資料後再去使用 push() 方法把物件給放到預先已建立的Array中。

ps. push()方法是原生的JavaScript的方法。

 

為什麼一定要把JSON資料轉為Array呢?

如果說從後端取得JSON資料後並沒有去做額外的處理,而只是單純的把JSON資料給呈現在頁面上,那就不需要大費周章的把JSON資料去轉為Array,

之所以要轉為Array,是因為前端語言中物件陣列的操作比單純使用JSON資料的操作要更容易,畢竟JSON資料是用於前後端資料交換使用,

不論是前端還是後端,要對JSON資料做進一步的處理都還是要先做轉換的動作。

 

在這邊我簡單的做的一個應用,把轉換為Array的資料給呈現在頁面上,

function ReadAllProducts(actionUrl)
{
  var result = GetData(actionUrl);
            
  var details = result.length + "<hr/>";
  $.each(result, function(i, item)
  {
    details += item["ProductID"] + "|" + item["ProductName"] + "|"  + item["CategoryID"] + "|" + item["CategoryName"] + "|"+ item["SupplierID"] + "|"+ item["CompanyName"] + "|"+"<br/>";
  });
  $('#Products').html(details);
}
頁面上的呈現:

image

 

篩選Array的資料

在前端程式中要對Array的資料做篩選的處理,jQuery有提供一個方法就是 $.grep(),這是用來過濾Array中的資料,把符合條件的資料給取出。

jQuery.grep()

http://api.jquery.com/jQuery.grep/

這邊要特別的注意一下 $.grep() 中的 function部分,「jQuery.grep( array, function(elementOfArray, indexInArray) [, invert] )

因為常用$.each() 的情況下,在 $.each() 中的function部分是 function(index, element) 而 $.grep() 的 fumction則是相反的,

function(elementOfArray, indexInArray)

在使用$.grep()方法時要特別留意這個地方,不要寫錯了而一直偵錯卻找不出原因,這裡就是常常發生問題的地方。

function GrepData()
{
  var result = GetData(ActionUrls.GetProducts);
  var currentData = $.grep(result, function(item, i)
  {
    return item["CategoryID"] == "1" && item["SupplierID"] == "16";
  });
  var details = currentData.length + "<hr/>";
  $.each(currentData, function(i, item)
  {
    details += item["ProductID"] + "|" + item["ProductName"] + "|"  + item["CategoryID"] + "|" + item["CategoryName"] + "|"+ item["SupplierID"] + "|"+ item["CompanyName"] + "|"+"<br/>";
  });
  $('#Products').html(details);
}

在上面的程式中,我們要篩選出符合兩個條件的資料,分別是 CategoryID == 1 以及 SupplierID == 16,最後再顯示到頁面上。

執行結果:

image

 

上面簡單說明了要如何把接收的JSON資料轉換維Array,並且更進一步做篩選的處理,

對於前端資料的處理,這些資料轉換與篩選的操作是經常會使用到的,所以要熟記這些前端處理的操作。

 

jQuery API 參考連結:

jQuery.ajax():http://api.jquery.com/jQuery.ajax/

jQuery.getJSON():http://api.jquery.com/jQuery.getJSON/

jQuery.each():http://api.jquery.com/jQuery.each/

JavaScript push() Method:http://www.w3schools.com/jsref/jsref_push.asp

jQuery.grep():http://api.jquery.com/jQuery.grep/

 

以上

7 則留言:

  1. mrkt 大你好

    想請問一下,從後端拿到 JSON 資料後,前端利用這些資料呈現後,若使用者輸入篩選條件後,進行對資料的篩選,請問你會直接在前端處理或者是將篩選條件送到後端處理後,由前端接收到 response 再呈現篩選的結果

    回覆刪除
    回覆
    1. 針對你的問題,我想我會說要看狀況,
      要看你所處理的資料是否需要做即時的資料處理反應,
      如果你是用於金融財務處理的系統,資料是隨時都在更動的,所以篩選條件就有需要送回後端處理再傳回前端,
      如果要篩選的資料並不是有即時顯示資料的需要時,例如一般新聞、文章顯示等,
      這些就可以不必送回後端去做篩選處理,

      不過,真的是要看使用情境的需求而定。

      刪除
  2. Kevin大 您好:
    方便請問一下文章中的第五張圖,觀察Json格式您所使用的工具是哪一種呢?感謝。

    回覆刪除
    回覆
    1. 那是 Firefox 瀏覽器的一個著名外掛「Firebug」http://getfirebug.com/
      我也曾經寫過介紹介紹文,Firebug 也有很多外掛可以使用,
      「Firefox 開發前端語言時的偵錯工具 Firebug 以及好用的套件」http://kevintsengtw.blogspot.tw/2011/10/firefox-firebug.html
      「使用 Fiddler2 外掛工具(Json Viewer)來檢視JSON資料」http://kevintsengtw.blogspot.tw/2011/07/fiddler2json.html
      .
      上面的文章都是三年前的資料,因為這三年有多次的更新,雖然功能主體大致上是一樣的,不過還是要以 Firebug 官網的資訊為準。

      刪除
  3. Kevin大您好
    我在測試「前端程式中,將JSON資料轉為Array」程式碼時一切完美,result矩陣也能拿到值
    直到最後要return回去時,result矩陣會突然變成空矩陣
    不知道Kevin大有沒有遇過這樣的問題?

    回覆刪除

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。