Mvvm 剔除视图模型分离,一般方法/最佳实践是什么?

Mvvm 剔除视图模型分离,一般方法/最佳实践是什么?,mvvm,knockout.js,viewmodel,dry,separation-of-concerns,Mvvm,Knockout.js,Viewmodel,Dry,Separation Of Concerns,我刚开始玩击倒JS,下面是一个场景示例 我有一个旅游者的名单,名单上有CRUD方法——所有的方法都很有效。现在,当我单击一个游客时,将会显示一个更详细的描述——这是一个针对该信息的新的AJAX服务器调用 我的问题是,我应该有一个主视图模型,其中包含我的TouristsViewModel和TouristsSinfoViewModel,这意味着TouristsViewModel应该与主视图耦合以修改TouristsInfoViewModel,还是我的TouristsViewModel应该实例化Tou

我刚开始玩击倒JS,下面是一个场景示例

我有一个旅游者的名单,名单上有CRUD方法——所有的方法都很有效。现在,当我单击一个游客时,将会显示一个更详细的描述——这是一个针对该信息的新的AJAX服务器调用

我的问题是,我应该有一个主视图模型,其中包含我的TouristsViewModel和TouristsSinfoViewModel,这意味着TouristsViewModel应该与主视图耦合以修改TouristsInfoViewModel,还是我的TouristsViewModel应该实例化TouristsInfoViewModel并调用ko.applyBindings

我已经看过了,但是我想避免引入太多的第三方插件


总而言之:分离视图和视图模型,同时在它们之间共享数据的一般方法是什么

花时间学习AMD,require.js就是一个很好的库。 将viewmodels分开,不要将其耦合。 击倒邮箱,amplify.js pub/sub在相互交流中非常有用。 请看一个单页应用程序框架。杜兰达尔是个不错的选择。 如果您不打算使用Durandal或SPA,即使如此,也要创建一个单独的模块来处理您与knockout的绑定。 每个视图都应具有相应的viewmodel。 将ajax调用分离到自己的模块中。例如:touristsRepository.js可能是一个模块,它将为您进行所有ajax调用。 与承诺一起工作。js或jquery的延迟承诺将帮助您解决问题。您的存储库应该返回承诺。 您的viewmodels应该是。。。本质上,它应该保存状态并提供视图交互处理程序。模型应该是它自己的文件。然后,ViewModel可以保存模型数据。 模型数据只能通过存储库检索。 我认为这将是一个体面的方法,对你来说会很有用

编辑-根据评论添加更多内容

1您可以在requirejs中使用填隙和导出来加载ko验证插件,而不是使用定义。除非您首先没有使用requirejs来加载它

2使用发布/订阅是不耦合的。当一个模块完全依赖于另一个模块的功能或存在时,就会发生耦合。考虑到MasterViewModel直接与另一个viewmodel通信,因此该模型是耦合的。在发布/订阅场景中,您的一个viewmodel将其称为Persons.js,即保存person对象。一旦保存,就应该更新本地缓存。在这种情况下,Persons.js在保存后会发送一条消息,说明Person已保存并传递它拥有的任何数据。ClearCache.js负责清除缓存。它只是在侦听已保存的消息以采取某些操作。耦合方式是Persons.js实例化ClearCache并直接调用其ClearCache方法。因此,Persons.js必须存在,clearCache.js必须存在。其中,在pub/sub中,即使clearCache.js不存在,Persons.js也可以继续存在

3这个问题的答案完全取决于你的申请要求。通常,我有一个名为binder.js的中间模块。js,侦听消息。所以,假设用户想要查看详细信息并点击游客。TouristsViewModel将发布一条消息,要求提供游客详细信息,并传递游客id或一些信息。活页夹正在监听此消息,它知道要实例化哪个viewmodel以及要采取什么操作。这样,您的ToursissView模型就完全不了解TouristsInfo视图模型。如果在另一个视图中,您列出了所有游客的名字和姓氏,而不必显示详细信息,则可以重复使用TouristsView模型,而无需不必要地引入TouristsInforViewModel。在这种情况下,不需要MasterViewModel


您的应用程序听起来像是单页应用程序的完美候选者。遵循单视图-单视图模型方法和单一责任方法。TouristsViewModel仅显示游客,TouristInfo视图Model将显示游客信息。他们俩都不知道对方的情况。我最近在一个有类似要求的项目上工作。演讲者,演讲者详细信息,会话,会话详细信息。我的视图模型中没有一个知道另一个。它们都是通过客户端路由和散列更改事件来管理的。

这里是一种通用方法

花时间学习AMD,require.js就是一个很好的库。 将viewmodels分开,不要将其耦合。 击倒邮箱,amplify.js pub/sub在相互交流中非常有用。 请看一个单页应用程序框架。杜兰达尔是个不错的选择。 如果您不打算使用Durandal或SPA,即使如此,也要创建一个单独的模块来处理您与knockout的绑定。 每个视图都应具有相应的viewmodel。 将ajax调用分离到自己的模块中。例如:touristsRepository.js可能是一个模块,它将为您进行所有ajax调用。 与承诺一起工作。js或jquery的延迟承诺将帮助您解决问题。您的存储库应该返回承诺。 您的viewmodels应该是。。。本质上,它应该保存状态并提供视图交互处理程序。模型应该是它自己的文件。然后,ViewModel可以保存模型数据。 模型数据只能通过存储库检索。 我认为这将是一个体面的方法,对你来说会很有用

编辑-根据评论添加更多内容

1您可以在requirejs中使用填隙和导出来加载ko验证插件,而不是使用定义。除非您首先没有使用requirejs来加载它

2使用发布/订阅是不耦合的。当一个模块完全依赖于另一个模块的功能或存在时,就会发生耦合。考虑到MasterViewModel直接与另一个viewmodel通信,因此该模型是耦合的。在发布/订阅场景中,您的一个viewmodel将其称为Persons.js,即保存person对象。一旦保存,就应该更新本地缓存。在这种情况下,Persons.js在保存后会发送一条消息,说明Person已保存并传递它拥有的任何数据。ClearCache.js负责清除缓存。它只是在侦听已保存的消息以采取某些操作。耦合方式是Persons.js实例化ClearCache并直接调用其ClearCache方法。因此,Persons.js必须存在,clearCache.js必须存在。其中,在pub/sub中,即使clearCache.js不存在,Persons.js也可以继续存在

3这个问题的答案完全取决于你的申请要求。通常,我有一个名为binder.js的中间模块。js,侦听消息。所以,假设用户想要查看详细信息并点击游客。TouristsViewModel将发布一条消息,要求提供游客详细信息,并传递游客id或一些信息。活页夹正在监听此消息,它知道要实例化哪个viewmodel以及要采取什么操作。这样,您的ToursissView模型就完全不了解TouristsInfo视图模型。如果在另一个视图中,您列出了所有游客的名字和姓氏,而不必显示详细信息,则可以重复使用TouristsView模型,而无需不必要地引入TouristsInforViewModel。在这种情况下,不需要MasterViewModel


您的应用程序听起来像是单页应用程序的完美候选者。遵循单视图-单视图模型方法和单一责任方法。TouristsViewModel仅显示游客,TouristInfo视图Model将显示游客信息。他们俩都不知道对方的情况。我最近在一个有类似要求的项目上工作。演讲者,演讲者详细信息,会话,会话详细信息。我的视图模型中没有一个知道另一个。它们都通过客户端路由和散列更改事件进行管理。

谢谢,这很有意义!我已经在使用Require了,它很棒,除了我必须在define中封装KO验证插件才能正常工作。分离AJAX调用,好主意!我可能会把它命名为touristsApi.js或touristsService.js,但无论如何!使用邮箱/放大,不考虑耦合?另外,根据我的问题,我将如何管理viewmodels?从主视图模型?主视图模型是否应该一次实例化所有视图模型?请详细说明+1.目前:对我的回答补充了更多。希望这会有所帮助。关于KO验证的填充,我尝试了它,但没有成功,虽然看起来像是一个已知的错误,所以我只是继续,并将其包装在一个define调用中,一切都很好。关于binder,在我的场景中,这会是我的MasterViewModel吗?另外,为什么你推荐使用promises?binder将是它自己的模块。你可以有一个main.js引导程序,当你的应用程序启动时,它将加载它并保持它正常运行。它不会是一个主视图模型。关于承诺,这是一个更好的方式来处理我们所谓的地狱。考虑到这一点,你只有1个成功的处理程序。您可以根据第一次调用的结果进行更多ajax调用,以此类推。您将得到一堆嵌套回调。有了承诺,你可以做这样的事情:当firstAjaxCall.then函数firstAjaxResult{}我开始使用Durandal,它工作得非常出色!谢谢你的建议!谢谢,这很有道理!我已经在使用Require了,它很棒,除了我必须在define中封装KO验证插件才能正常工作。分离AJAX调用,好主意!我可能会把它命名为touristsApi.js或touristsService.js,但无论如何!使用邮箱/放大,不考虑耦合?另外,根据我的问题,我将如何管理viewmodels?从主视图模型?主视图模型是否应实例化所有视图模式
马上就来?请详细说明+1.目前:对我的回答补充了更多。希望这会有所帮助。关于KO验证的填充,我尝试了它,但没有成功,虽然看起来像是一个已知的错误,所以我只是继续,并将其包装在一个define调用中,一切都很好。关于binder,在我的场景中,这会是我的MasterViewModel吗?另外,为什么你推荐使用promises?binder将是它自己的模块。你可以有一个main.js引导程序,当你的应用程序启动时,它将加载它并保持它正常运行。它不会是一个主视图模型。关于承诺,这是一个更好的方式来处理我们所谓的地狱。考虑到这一点,你只有1个成功的处理程序。您可以根据第一次调用的结果进行更多ajax调用,以此类推。您将得到一堆嵌套回调。有了承诺,你可以做这样的事情:当firstAjaxCall.then函数firstAjaxResult{}我开始使用Durandal,它工作得非常出色!谢谢你的建议!