Best Practice with Multiple ViewModels

两盒软妹~` 提交于 2019-12-11 01:54:46

问题


I have an edit page with 3 logical parts to the page:

  • Header
  • Order
  • Payment

The user is allowed to edit each section at once and submit the changes with a single submit button.

This page is rather large in terms of functionality and the object the user is editing.

The object being sent to the page for edit is a JSON object with some properties that don't get edited but need to pass back on submit.

Is the best practice in this scenario to have the following VM structure:

  • Master VM
    • Header VM
    • Order VM
    • Payment VM

I would assign each VM to the appropriate section of the page. What's the easiest way to merge changes back to the master JSON object so I can submit just that one object to the server?


回答1:


The splitting up of the page looks logical, and shouldn't be a problem by itself. But there are different approaches to how you are going to do it, which bring their own challenges.

The 'easy' way out would be, -like you proposed-, to have a tree-like masterview, with child viewmodels. I remember this as a recommended approach when I started with Knockout a year or 2 ago. In vanilla JS you would get something like:

function childVM() { this.prop = ko.observable(0); }
function masterVM() { 
  this.children = ko.observableArray([new childVM(), new childVM()]); 
}

But you could just as well (or even rather) use ko.components, which after all serve specifically the purpose of breaking down large code into modules (and work very well with RequireJS). (By the way you can embed components into one another, though it does make them dependant). An example of a component using the previous code:

ko.components.register('child', {
  viewModel: function childVM(params) { this.prop = ko.observable(0||params.number)},
  template: { element: 'child' }); //looks for tmpl with id 'child'
function masterVM() { 
  this.children = ko.observableArray([new childVM(), new childVM()]); 
}

With this approach, you could also use custom elements, eg: <child params='{number: 4}></child>. Essentially components work the same as the vanilla approach, except they are bound to a parent through the view, not explicitly in the viewModel. As a next step, which enables child models or components to communicate with one another,would be using a pub-sub system. See here for more info: http://www.knockmeout.net/2012/05/using-ko-native-pubsub.html

To get the data from your different view models after submit would be as simple as using a ko.mapping.toJS call on each child model (using the mapping plugin, it converts all observables to regular JS), combine them, stringify to JSON, and send it.



来源:https://stackoverflow.com/questions/27946789/best-practice-with-multiple-viewmodels

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!