2017-04-10 45 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我不确定这个)。至于我,我可能不会使用这种模式,因为它似乎过于冗长。