La scène est comme ceci :
Une telle opération doit s'appuyer sur plusieurs modèles en même temps, donc ces codes ne seront pas écrits dans un certain modèle.
Il peut s'agir par exemple de Backbone, écrit en ViewController... Mais cette réutilisation de code n'est pas bonne, et la View sera chamboulée.
Ma solution actuelle consiste à utiliser un seul fichier pour collecter la plupart des opérations du modèle, mais le problème est que ce fichier continuera de croître en taille et en encombrement.
Alors, comment résoudre un tel problème ?
La question étendue est : comment organiser cette partie du code ?
Par exemple, j’ai utilisé la solution Flux de React et j’ai essayé de clarifier le processus, mais j’ai découvert que je ne savais pas où mettre cette partie du code..
Flux convertit les opérations des utilisateurs en actions et Store surveille ces actions via Dispatcher,
Lorsqu'une Action correspond à plusieurs Stores... le problème se pose :
Dois-je utiliser plusieurs actions pour correspondre respectivement aux magasins, ou une action doit-elle être surveillée par plusieurs magasins ?
用户点击按钮本质上跟用户通过URL访问一样,都是一种『输入』,所以问题和处理机制都是一样的:在view层代码里监听『输入』,处理一些view层(比如按钮组件的toggle、URL的矫正)内部的状态变化,生成/提取出纯粹的、抽象层级更高的(跟view组件或URL细节无关)数据/消息,用某种事件机制广播出去,之后就跟自己没关系了,接下来如果有controller层的话,在这部分的代码里监听这些事件,调用相应model对象的方法(其中可能封装了model对象自己之间的依赖关系和调用,但这里的一对多复杂性不会暴露到外面去),同时也监听某些model对象的状态变化,调用相应view对象的方法(或是重新渲染Virtual DOM)。所有东西绑定完成。
比如我平时用NervJS(model) + DermJS(view)+ URLKit(route) 这样的搭配,NervJS和DermJS对象都有自带的事件方法,此外也可以在view/model对象初始化时传入统一的bus事件对象。
你写一个UI component的时候当然不会希望它依赖特定的model,写一个model组件的时候,也不会希望它依赖特定UI,所以一对多之类的绑定是在另一个地方(专门的业务逻辑代码)完成的,view对象和model对象不需要也不应该知道对方有几个、是哪些,所以也不可能『多个 Actions 分别对应 Store』。
至于『单独一个文件』、『不断变大变乱』的问题,跟配置路由的文件也是一回事,可以参考相关经验。
flux里,如果需要一个动作对应多个Store,其实也是很好解决的。
在Store里面register回调的时候,可以都对这个动作进行相应就可以了,还可以通过
waitFor来改变相应的顺序。如果担心代码变乱的话,可以再单独写一个
constants文件,定义好触发的事件名称就可以了。举个例子:
点击一个按钮,触发
send事件,会更新两个Store分别是StoreA和StoreB。可以写一个constants.js,先定义事件名称:constants:
然后在两个
Store里面分别注册回调:StoreA:
StoreB:
在触发点击事件的时候,在
Action中触发Disp的这个事件,就会顺序执行在StoreA和StoreB中注册的回调了:)当这种情况出现时,我通常想到的是,可不可以在在他们中间加上一层了。
如果你没看过,或者看过但忘了,这是篇值得读的文章:
Patterns For Large-Scale JavaScript Application Architecture
简单而言,你需要有些“约定俗成”的东西,让view和model无需相互依赖(不管是1:1的依赖,还是1:N的依赖)。
用简单的event和observer pattern也可以,如果业务逻辑很复杂,用mediator完成模块间的通信和同步。
PS:理想的情况是,你的每个模块都只知道自己(触发什么事件,聆听什么事件),除此之外都不管,更不会知道对方的instance,或者mediator的instance。