MVP 是從經典的模式MVC演變而來,它們的基本思想有相通的地方:Controller/Presenter負責邏輯的處理,Model提供數據,View負 責顯示。做爲一種新的模式,MVP與MVC有着一個重大的區別:在MVP中View並不直接使用Model,它們之間的通訊是經過Presenter (MVC中的Controller)來進行的,全部的交互都發生在Presenter內部,而在MVC中View會從直接Model中讀取數據而不是經過 Controller。javascript
在MVC裏,View是能夠直接訪問Model的!從而,View裏會包含Model信息,不可避免的還要包括一些 業務邏輯。 在MVC模型裏,更關注的Model的不變,而同時有多個對Model的不一樣顯示,及View。因此,在MVC模型裏,Model不依賴於View,可是 View是依賴於Model的。不只如此,由於有一些業務邏輯在View裏實現了,致使要更改View也是比較困難的,至少那些業務邏輯是沒法重用的。php
MVVM在概念上是真正將頁面與數據邏輯分離的模式,在開發方式上,它是真正將前臺代碼開發者(JS+HTML)與後臺代碼開發者分離的模式(asp,asp.net,php,jsp)。html
在MVP裏,Presenter徹底把Model和View進行了分離,主要的程序邏輯在Presenter裏實現。並且,Presenter與具體的 View是沒有直接關聯的,而是經過定義好的接口進行交互,從而使得在變動View時候能夠保持Presenter的不變,即重用!前端
不只如此,咱們還能夠編寫測試用的View,模擬用戶的各類操做,從而實現對Presenter的測試--而不須要使用自動化的測試工具。 咱們甚至能夠在Model和View都沒有完成時候,就能夠經過編寫Mock Object(即實現了Model和View的接口,但沒有具體的內容的)來測試Presenter的邏輯。java
在MVP裏,應用程序的邏輯主要在Presenter來實現,其中的View是很薄的一層。所以就有人提出了Presenter First的設計模式,就是根據User Story來首先設計和開發Presenter。在這個過程當中,View是很簡單的,可以把信息顯示清楚就能夠了。在後面,根據須要再隨便更改View, 而對Presenter沒有任何的影響了。 若是要實現的UI比較複雜,並且相關的顯示邏輯還跟Model有關係,就能夠在View和Presenter之間放置一個Adapter。由這個 Adapter來訪問Model和View,避免二者之間的關聯。而同時,由於Adapter實現了View的接口,從而能夠保證與Presenter之 間接口的不變。這樣就能夠保證View和Presenter之間接口的簡潔,又不失去UI的靈活性。 在MVP模式裏,View只應該有簡單的Set/Get的方法,用戶輸入和設置界面顯示的內容,除此就不該該有更多的內容,毫不允許直接訪問 Model--這就是與MVC很大的不一樣之處。數據庫
目前咱們提倡的MVC已經與MVP沒有太大區別,View依然是很薄的一層,不進行與Model的邏輯處理,只進行簡單的頁面顯示的邏輯處理。設計模式
微軟的WPF帶來了新的技術體驗,如Sliverlight、音頻、視頻、3D、動畫……,這致使了軟件UI 層更加細節化、可定製化。同時,在技術層面,WPF(原來winform那邊的)也帶來了 諸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。MVVM(Model-View- ViewModel)框架的由來即是MVP(Model-View-Presenter)模式與WPF結合的應用方式時發展演變過來的一種新型架構框架。 它立足於原有MVP框架而且把WPF的新特性揉合進去,以應對客戶日益複雜的需求變化。api
前端工程師們與程序開發人員們實現了真正的分離,固然,爲了減小重複代碼量,前端人員有必要了解一個數據庫結構。前端工程師
Knockoutjs能夠靈活的實現數據的綁定工做,對於前臺開發人員來講,不須要關心後臺數據以何種方式產生,它們只須要關心數據的屬性簽名便可,對於程序開發人員來講,它們關心的是數據產生的接口,包括簡單的CURD操做接口,程序開發人員完成能夠把這些邏輯寫在單獨的JS文件中,由HTML頁面指定引用,真實數據便可完成綁定工做。架構
使用knockoutjs來實現MVC中的MVVM模式
html代碼:
<table> <thead> <tr> <th>編號</th> <th>姓名</th> <th>電話</th> <th>操做</th> </tr> </thead> <tbody data-bind="template:{name:'list',foreach: lines}"> </tbody> <tfoot> <tr> <td colspan="4"> <button data-bind='click: addLine'>Add</button></td> </tr> </tfoot> </table> <script type="text/html" id="list"> <tr> <td><span data-bind="text:Id"></span></td> <td> <span data-bind="text: Name"></span> </td> <td> <span data-bind="text: PhoneNo"></span> </td> <td> <a href='#' data-bind='click: $parent.removeLine'>Remove</a> </td> </tr> </script>
Controller層C#代碼獲得數據:
public IEnumerable<Contact> Get() { Contact[] contacts = new Contact[] { new Contact{Id=1, Name="張三", PhoneNo="123", EmailAddress="zhangsan@gmail.com"}, new Contact{Id=2, Name="李四", PhoneNo="456", EmailAddress="lisi@gmail.com"}, new Contact{Id=3, Name="王五", PhoneNo="789", EmailAddress="wangwu@gmail.com"}, }; return contacts; }
knockoutjs代碼用來綁定數據和實現頁面的交互
<script type="text/javascript"> var CartLine = function () { var self = this; self.Id = ko.observable(); self.Name = ko.observable(); self.PhoneNo = ko.observable(135); self.EmailAddress = ko.observable("@"); }; $.getJSON("http://localhost:2166/api/values/", function (data) { var Cart = function () { // Stores an array of lines, and from these, can work out the grandTotal var self = this; //self.lines = ko.observableArray([new CartLine()]); self.lines = ko.observableArray(data); // Operations self.addLine = function () { self.lines.push(new CartLine()) }; self.removeLine = function (line) { self.lines.remove(line) }; } ko.applyBindings(new Cart()); });
OK,到了這裏,一個MVVM風格的實例已經講解完了,下回咱們將逐步來學習knockoutjs。