2014年3月4日 星期二

ASP.NET MVC 4 WebApi 與 Extjs 的結合 -- 列表操作列 ( Action Column )

此篇文章延伸 ASP.NET MVC 4 WebApi 與 Extjs 的結合 -- 列表 ( List ) 繼續做列表操作列的功能加強。

通常這種操作列 ( Action Column ) 通常使用在單行資料更新或資料刪除,與小弟在 2012 年發布的 GridView 新增、刪除、修改以及排序 功能是非常類似的,只是這是純 ASP.NET 控制項與事件做出來的,而該篇文章是要利用 ASP.NET MVC 4 WebApi 與 Extjs 做出相同的功能。

actioncolumn

在 items 內多加一個欄位,xtype 為 actioncolumn,在此就先多加一個更新和刪除的按鈕:
{
    text: 'ActionColumn',
    flex: 0.5,
    xtype: 'actioncolumn',
    menuDisabled: true,
    renderer: function (value, metadata, record, rowIndex, columnIndex) {

    },
    items: [
        {
            icon: '/Images/Icons/note-add.png',
            tooltip: '加',
            scope: this,
            handler: function (grid, rowIndex, colIndex) {
                
            }
        },
        { weight: 10 },
        {
            icon: '/Images/Icons/del.png',
            tooltip: '刪除',
            scope: this,
            handler: function (grid, rowIndex, colIndex) {
               
            }
        },
    ]
},

執行後畫面如下

renderer

此功能可以格式化該列的資料格式或者是按照自定義的 HTML 顯示最後的樣板。
在 renderer 加上,將 LastName 為 '哈哈' 的按鈕圖示改為 pig.png
renderer: function (value, metadata, record, rowIndex, columnIndex) {
    if (record.get('LastName') == '哈哈') {
        gridPanel.columns[columnIndex].items[0].icon = '/Images/Icons/pig.png';
    }
},
而在其中一個按鈕加上在按鈕按下時,將 LastName 改為 '哈哈' 的功能:
{
    icon: '/Images/Icons/note-add.png',
    tooltip: '加',
    scope: this,
    handler: function (grid, rowIndex, colIndex) {
        rec.set('LastName', '哈哈');
        
    }
},

執行後點擊按鈕圖示就會改變為如以下圖

更新與刪除

更新與刪除兩個按鈕可以結合 WebApi 達到不像以往 ASP.NET 做完後還必須 ReLoad 才做完事件內容,而是按下後並無任何畫面跳動就會將資料用 ajax 送到 API 後處理,頁面上則是將該筆資料保留或移除,其實是只做 HTML 上的保留或移除;然而在重新整理畫面後,資料因為更新或移除了,所以讀到的也會是最新的資料。

首先要準備 API,刪除與更新:
public HttpResponseMessage Put(int id, Employees employee)
{
    if (!ModelState.IsValid)
    {
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
    }

    if (id != employee.EmployeeID)
    {
        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }

    db.Entry(employee).State = EntityState.Modified;

    try
    {
        db.SaveChanges();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
    }

    return Request.CreateResponse(HttpStatusCode.OK);
}

public HttpResponseMessage Delete(int id)
{
    Employees employee = db.Employees.Find(id);
    if (employee == null)
    {
        return Request.CreateResponse(HttpStatusCode.NotFound);
    }

    db.Employees.Remove(employee);

    try
    {
        db.SaveChanges();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
    }

    return Request.CreateResponse(HttpStatusCode.OK, employee);
}

在畫面上可以這樣設定
{
    icon: '/Images/Icons/note-add.png',
    tooltip: '加',
    scope: this,
    handler: function (grid, rowIndex, colIndex) {
        var rec = grid.getStore().getAt(rowIndex);
        rec.set('Photo', '')

        $.ajax({
            url: 'http://localhost/api/Employee/Put?id=' + rec.get('EmployeeID'),
            data: rec.data,
            type: 'PUT',
            error: function () { alert('Error!!'); },
            success: function () {
                alert('更新成功');
            }
        });
        
    }
},
{ weight: 10 },
{
    icon: '/Images/Icons/del.png',
    tooltip: '刪除',
    scope: this,
    handler: function (grid, rowIndex, colIndex) {
        var rec = grid.getStore().getAt(rowIndex);
        console.log(rec);

        $.ajax({
            url: 'http://localhost/api/Employee/Delete?id=' + rec.get('EmployeeID'),
            type: 'DELETE',
            error: function () { alert('Error!!'); },
            success: function () {
                alert('刪除成功');
            }
        });
        
        // 畫面上移除該列
        grid.getStore().removeAt(rowIndex);

    }
},

執行後按下刪除或更新在 API 都接收到值:

按鈕失效

通常有些情況下,必須要讓按鈕失效,例如產品與產品分類的關係,在編輯產品分類的畫面中,若是產品分類底下還有產品,則不能將產品分類刪除,必須等到產品分類下沒有產品了才能刪除,要不然在開啟產品頁面時,則會對應不到產品分類。上面的例子或許舉得不好,但是有更多種情況必須要將某些按鈕失效,不然會對資料或系統造成錯誤的問題。

在 Extjs 中,使用 isDisabled 屬性,並依照該列顯示或隱藏的資料判斷此按鈕是否失效,順便一提,在頁面上無法完全擋住使用者按下按鈕,所以必須在 API 再判斷一次,這樣才能不會讓資料造成對應不到的問題。

{
    isDisabled: function (view, rowIndex, colIndex, item, record) {
        if (record.get('EmployeeID') > 4) {
            return true;
        } else {
            return false;
        }
    },
    icon: '/Images/Icons/del.png',
    tooltip: '刪除',
    scope: this,
    handler: function (grid, rowIndex, colIndex) {
        alert();

    }
},

執行後如以下畫面


沒有留言 :

張貼留言

Related Posts Plugin for WordPress, Blogger...