程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> 淺談ASP.NET MVC在前端開發中的局限性

淺談ASP.NET MVC在前端開發中的局限性

編輯:關於ASP.NET

ASP.NET MVC

如果你還沒有接觸過後端的MVC框架的話,不妨先看看下面這段ASP.NET MVC代碼並且了解一下後端MVC的工 作原理。它摘自ASP.NET MVC教程中非常著名的項目MVC Music Store一段Controller組件代碼:

public class StoreManagerController : Controller
{
    private MusicStoreEntities db = new MusicStoreEntities();
    // GET: /StoreManager/
    public ViewResult Index()
    {
        var albums = db.Albums.Include(a => a.Genre).Include(a => a.Artist);
        return View(albums.ToList());
    }

    // GET: /StoreManager/Details/5

    public ViewResult Details(int id)
    {
        Album album = db.Albums.Find(id);
        return View(album);
    }
}

我們知道Controller的職責之一是負責響應用戶在視圖上的行為,而具體每個行為應如何進行響應,需要 落實到Controller具體的方法上,這個方法我們可以稱之為action。上面代碼中的兩個公開方法Index()與 Details()就是兩個action。它們都屬於StoreManager這個Controller。如果你有使用過前端的Ember.js的話 ,應該對這兩個概念非常熟悉。

但問題來了,如何將用戶在視圖上的行為,與響應行為的方法action關聯起來?甚至與Controller關聯起 來? URL便是方法之一。上面代碼每個action上的注釋便代表這個這個action對應的URL。也就是說,當用戶 點擊該URL時,框架中的Router服務便能通過URL解析出應該調用哪個Controller及該Controller下的哪一個 action進行響應,以上面的例子為例,可以知道URL的規則為{controller}/{action}/{id}。

那麼響應的結果應該是什麼呢?從上面的代碼ViewResult和return View()兩處可以看出,兩個action返回 的都是新的視圖。

舉一個最熟悉的現有MVC站點的例子便是github。你會發現你在github網站上的每一處點擊都有唯一的URL 對應,每一次交互的結果都是服務器返回新的頁面。它使用javascript非常少,比如當你選擇編輯時,它也會 跳轉到一個新的頁面,而非在當前頁彈出一個編輯框。

為什麼首先要聊這麼多的服務器端MVC框架的特性。因為接下來回過頭來看前端的MVC框架時,你會發現有 非常多的差異之處。

Javascript MVC

從上面可以看出,服務器端的MVC框架服務的是整個站點,它依靠不斷的返回頁面來響應用戶請求,因此 Router服務至關重要。而使用MVC框架的前端頁面,大多數是Single Page Application,甚至還不如單頁面, 只是頁面上的某一個組件,比如一個Slide。因此將用戶的行為轉化為URL是不現實。你或許會說的確無法生產 新的頁面,那麼降低頁面粒度如何呢?也就是說在服務器端一個URL映射的是一個頁面,那麼我們將URL映射為 頁面的某個區域或者功能呢?

比如以下面這段Backbone.js的TodoList應用Router為例:

var TodoRouter = Backbone.Router.extend({
    routes: {
        'todo/add': 'add', // 新增項
        'todo/edit/:id': 'edit', // 編輯項
        'todo/remove/:id': 'remove', // 刪除項

        'filter/completed': 'filterCompleted', // 過濾出已完成
        'filter/uncompleted': 'filterUncompleted' // 過濾出未完成
    }
    // Todo
});

如果依照這樣Route規劃,我們希望當用戶輸入http://example.com#todo/add時,我們彈出的是一個新增 輸入框;而當用戶輸入http://example.com#todo/edit/123456頁面出現編輯id為123456的這條記事的編輯框 。這樣我們便將URL映射的頁面粒度降低為輸入框粒度。

但是這樣會引起另一個問題,注意上面route的差別:todo/域名下操作的是單條的記錄,而filter/域名下 操作的是對列表進行篩選。所以還不得不考慮一種情況,如果用戶想在篩選的情況下可否對每一項進行操作? 如果允許的話,參考排列組合,route是否需要新增為2 x 3 = 6項?如新增 http://example.com#filter/completed/todo/add這樣的路由。

這樣的設定明顯是不合理的。之所以會產生這樣的問題是因為對後端而言URL與頁面是一一對應的關系。而 如果降低頁面粒度的話,無法將頁面功能與URL對應起來,或者說如果想讓URl覆蓋單一頁面上的所有功能的成 本太高了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved