在Flex MVC框架中在视图和模型之间传递数据

时间:2012-07-07 00:28:39

标签: flex model-view-controller actionscript mxml

我从来没有使用过Flex / Actionscript,所以请原谅我,如果我问了一些显而易见的事情,但是在写这篇文章之前我已经做了3天(包括搜索google和stackoverflow)。

我被要求修改用基于mini-IoC的MVC框架制作的Flex 4编写的游戏。我被要求做的两个mod是屏幕上的游戏,它在介绍屏幕上显示最终得分和难度选择。我已经让游戏通过屏幕,并成功设法让控制器在游戏计时器用完时启动它。

所以现在,游戏结构如下:

Intro View -> Game View -> Game Over View

    ^                            |
    |__________ (retry?) ________|

第一个问题是将得分从mainGame ActionScript文件传递到屏幕上的游戏。

我尝试过的事情:

  • 在gameOverViewBase中导入mainGame并在gameOverView mxml文件中调用mainGame.score变量。

- 编辑!!! =如果我将mainGame中的得分变量更改为常量,则上述方法有效,但如果它仍然是变量,则控制器将不会加载gameOverView并且游戏位于空的mainGame视图中。

  • 每当玩家在游戏中得分时,制作一个在gameOverViewBase中添加新得分变量的函数。
  • 当MainGame结束时,将乐谱作为参数传递给GameOverView

controller.loadGameOver(score);

这似乎是最合理的方式。所以我通过设置loadGameOver的游戏的其他组件跟随函数,以整数作为参数,直到我到达主游戏actionscript文件:

public function loadGameOver(score:int) : void
    {
        loadView(GameOverView);
    }

loadView函数(如下所示)是我卡住的地方,因为我无法看到传递'score'参数的位置。它看起来像这样:

private function loadView(viewClass:Class, modelClass:Class = null) : void
    {

        var view:View = new viewClass();
        if(!view) throw new Error("Could not load view");

        viewContainer.removeAllElements();
        viewContainer.addElement(view);         

        view.controller = this;

    }

第二个问题是在介绍屏幕上选择难度。我在mxml文件中使用3个按钮(简单,正常,硬)和ActionScript中的每个按钮完成了此操作:

protected function onEasyButtonClick() : void
    {
        set = "easy"
        controller.loadMainGame(set);
    }

再一次,我最终得到了上面的loadView函数。

总结:我需要知道如何在视图和模型之间传递数据。如果这不是理想的方法,我愿意接受你认为更好的任何其他方法。

谢谢!

P.S。我可以将源代码发送给任何想要帮助的人:)

1 个答案:

答案 0 :(得分:2)

您没有指定您正在使用的哪个MVC框架会有所帮助。但是,分数绝对应该是模型的属性,并且模型数据应该可以直接访问,也许可以通过绑定(感谢weltraumpirat)或通过某个中间类来访问。

我建议您查看一些现有的视图类,并尝试弄清楚它们是如何提供模型数据的。您可以使用此方法获取视图所需的数据。

<强> [编辑]:

mainGame实例上未设置GameOverView属性,因此您无法通过绑定或跟踪访问其score属性。控制器类的loadView方法接受Model类引用,它用于构造新Model实例以供新View使用。不幸的是,这对您没有用,因为GameOverView需要为MainGame创建的MainGameView实例(包含当前得分)。

我不知道以下内容是否符合您正在使用的框架的理念。但是,我会更改loadView方法以接受Model的实例而不是类引用,并在实例化控制器时创建并缓存对MainGame实例的引用。这样,您可以在创建ModelMainGameView时向GameOverView public class WhackAMoleBase extends Application implements IGameController { public var viewContainer:Group; private var mainGame:MainGame public function WhackAMoleBase() : void { super(); // Create and cache an instance of the main game Model mainGame = new MainGame(); addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete); } public function loadIntroduction() : void { loadView(IntroductionView); } public function loadMainGame() : void { loadView(MainGameView, mainGame); } public function loadGameOver() : void { // Use the same instance of MainGame which the MainGameView // has been using as the Model for the GameOverView loadView(GameOverView, mainGame); } // Accept a Model instance rather than a class Reference private function loadView(viewClass:Class, model:Model = null) : void { //Create a new instance of the supplied view var view:View = new viewClass(); if(!view) throw new Error("Could not load view"); //Clear any previous views in the container and add viewContainer.removeAllElements(); viewContainer.addElement(view); //Property based dependency injection view.controller = this; //There may or may not be a model required for the //requested view; check and instantiate appropriately if(model) { //Give model reference to the controller //and link the view up to the model model.controller = this; view.model = model; } } private function onCreationComplete(event:FlexEvent) : void { //When the application is first created, we want to show the introductory view loadView(IntroductionView); } } 传递相同的{{1}}引用。

{{1}}