了解AMD:如何使用单向模块关系处理响应流

时间:2015-05-08 16:03:33

标签: javascript jquery requirejs amd

如果你愿意的话,考虑一个具有一些独特观点/状态的应用程序 - 让我们把它称为游戏。你有一个世界屏幕,一个战斗画面,一个多人游戏界面,也许还有一两个小游戏。

为了争论,每个视图之间没有共同的代码,因此它非常适合AMD - 一个中央控制器/调度程序,每个游戏状态分成一个单独的文件/视图。

dispatcher.core.js
>   overworld.view.js
>   battle.view.js
>   tournament.view.js
>   minigame.view.js

输入和键命令被路由到调度程序,并向下流入当前活动视图,然后根据需要操作DOM。单向的AMD关系,到目前为止一直很好。

我被挂断的是响应流程。通过系统的API响应数据是多种多样的,通常同时影响多个视图。考虑这种情况:

  1. 用户按下按钮移动
  2. 键命令被路由到地图视图以进行移动动画
  3. Map向服务器发送AJAX请求以获取移动结果
  4. AJAX返回"战斗开始"对调度员的回应
  5. Dispatcher告诉地图视图禁用自身,然后战斗视图到init
  6. 调度员就是为此而设计的 - 接收指令并分发。这似乎是一个明显的选择,而不仅仅是让观点直接相互影响。

    但是,这里存在一个根本缺陷 - 一旦AJAX结果从视图发送到调度程序,调度程序和视图之间的单向关系就会被违反。您既可以使用调度程序进行AJAX回调,也可以指示调度程序为您调用AJAX - 但无论哪种方式,视图都需要一种方式来引用调度程序,据我所知,它违反了AMD的核心原则。 。对于我的生活,我无法弄清楚如何正确实施!

    我的问题是 - 如何正确实现这样的结构?这是AMD的限制,还是我误解了它在更深层次上的使用?

    这个问题旨在针对更多的一般情况,但如果它完全影响答案,我分别使用Require和jQuery for AMD和AJAX。

2 个答案:

答案 0 :(得分:1)

  

这是AMD的限制,还是我误解了它在更深层次上的使用?

AMD无论如何强加 对象实例之间的单向关系。强烈建议避免它(因为即使这不是绝对要求)是模块之间的循环依赖 。对AMD来说重要的依赖类型是加载依赖项。

你当然可以拥有一个名为sqldiff db2.sqlite db1.sqlite 的模块:

dispatcher

define(function () { function Dispatcher(views) { this.views = views; for (var ix = 0, view; (view = views[ix]); ++ix) view.init(this); } return Dispatcher; }); viewA,其结构如下:

viewB

您的主要模块可以:

define(function () {
    function View() {
        // ...
    }

    View.prototype.init = function (dispatcher) {
        this.dispatcher = dispatcher;
    };

    // Etc...

    return View;
});

以上是可能的示意性示例,而不是良好设计的处方。无论如何,只要AMD关注对象之间的循环引用,那就完全可行了。

答案 1 :(得分:1)

这里没有任何关于AMD的限制;它完全是关于模块本身的设计。

处理此问题的常用方法是使用demo

<div id="container"> <div class="item1 left">item1</div> <div class="item2 right">item2</div> <div class="item3 right">item3</div> </div>可以直接在dispatcher上调用方法,但view会发出view可以侦听和响应的事件,从而无需循环引用(因为dispatcher并不关心事件的去向,所以它不需要引用view。)

适合您的示例工作流程,它可能如下所示:

  1. dispatcher跟踪按键
  2. overworld动画响应按键
  3. overworldoverworld

    发出'move'事件
    dispatcher
  4. 响应告诉// overworld.view this.emit('move', {data}); // dispatcher overworld.on('move', getMoveResult) // getMoveResult fires AJAX request 是时候战斗了
  5. dispatcher更新观看次数

    dispatcher