2017-04-10 41 views
1

我正在使用angular2在Web應用程序上工作。 MVVVM模式:模型視圖ViewModel,在angular2中我們有:模型類,可以從服務器端提取數據的服務以及View和組件的模板。我想知道我們如何在angular2項目中正確應用MVVM架構?MVVM與Angular2應用

+1

這些MVC模式縮寫非常模糊。請發佈演示您嘗試完成的代碼,您嘗試過的以及失敗的地方。 –

回答

0

在一個典型的MVVM模式,你有模型對象(這是所有僞代碼):

class MyModel { 
    public int id; 
    public string foo; 
    public int bar; 
    public date createdOn; 
} 

然後你有一個觀點:

<div>{{myModelBar}}</div> 
<div>{{myModelFoo}}</div> 
<div>{{anotherModelBar}}</div> 

你怎麼看的視圖和模型不相關?該視圖需要模型中的一些屬性,但不是全部。該視圖還需要模型中不存在的屬性。這是需要一個視圖模型進來:

class MyViewModel { 
    public string myModelFoo; 
    public int myModelBar; 
    public int anotherModelBar; 
} 

現在,我們的觀點有一個模型,它可以實際使用。那麼我們如何從模型到ViewModel到視圖?我們需要一個控制器:

class Controller() { 
    var modelA = new MyModel(); 
    modelA.foo = "Foo"; 
    modelA.bar = 1; 
    var modelB = new MyModel(); 
    modelB.bar = 2; 

    var viewModel = new MyViewModel(); 
    viewModel.myModelFoo = modelA.foo; 
    viewModel.myModelBar = modelA.bar; 
    viewModel.anotherModelBar = modelB.bar; 

    // The view function here would retrieve the view and combine it with the ViewModel 
    var view = View('path_to_our_view_file', viewModel); 

    return view; 
} 

這是MVVMC模式。我會插入並說,MVVM模式本身是無用的,因爲你的模型,視圖和視圖模型沒有任何關於視圖或如何編寫視圖的行爲。我在MVVM聲稱的框架中看到的是,ViewModel通常是Controller和ViewModel的混搭,或者他們認爲該模式是無控制器的,因爲沒有路由。但是,我會說在這種情況下,路由被隱含在ViewModel正在處理特定視圖的情況下。

應該明顯的是Angular並不嚴格遵守這種模式。但是,大多數概念是相似的。你仍然有一個控制器和視圖,它們只是以組件的形式混合在一起。就控制器而言,有關Angular 2的有趣之處在於,您可以實際路由到控制器,並且暗示通過分配給組件的模板標記進行路由。但結果是一樣的,你可以通過某種方式調用或路由到組件,以檢索視圖。與許多框架一樣,模型圖層由您來創建。

那麼ViewModel圖層在哪裏?我會建議,因爲組件中的所有公共變量都可以被View所訪問,所以ViewModel層是Component類的屬性。在典型的服務器客戶端應用程序中,客戶端必須向服務器發出請求並且服務器返回視圖,您需要在每次調用時重建狀態。這要求您在每次調用時都要關閉MVVMC鏈:Controller - > Model - > ViewModel - > View。在Angular中的客戶端應用程序中,控制器爲視圖保存狀態,所以這就是ViewModel所在的位置。

所以問題就變成了,我們如何區分視圖和模型的問題。您只需要在視圖中直接使用模型即可。一種方法是創建一個單獨的視圖模型作爲一個類。

class MyComponentViewModel { 
    name: string; 
    list: Array<string>; 
} 

@Component({ 
    selector: 'my-component', 
    template: `<div>{{model.name}}</div> 
       <ul> 
       <li *ngFor="let item of (model.list | async)">{{item}}</li> 
       </ul>` 
}) 
class MyComponent { 
    model: MyComponentViewModel; 
    private propertyA: string 

    constructor(private dataService: DataService) { 
     this.model = new MyComponentViewModel(); 
     this.model.list = []; 

     let page = dataService.getCurrentPage(); 
     let children = dataService.getPageChildren(page.id).subscribe(pages => { 
      this.model.list = []; 
      for(let page of pages) { 
       this.model.list.push(page.title); 
      } 
     }) 

     this.model.name = page.title; 
    } 
} 

沒有測試過任何代碼,希望您購買該產品。你可以創建你自己的視圖模型,而不是弄髒你的組件類的屬性,你可以把視圖屬性放在它們自己的類中。如果你現在有一份合同可以使用(只要你堅持這種模式),這種方法的優點將是更清晰的組件和與觀點分離的擔憂。缺點是它稍微冗長一些,將某些類型轉換爲更適合視圖模型的更通用的類型可能比較困難,因爲您將所有屬性放在一個對象上(I我不確定這個)。至於我,我可能不會使用這種模式,因爲它似乎過於冗長。