我处于为新项目设置架构的初期阶段。数据驱动的Flex UI,位于网页内,为MySQL数据调用Amfphp服务以填充Flex UI中的元素。

关于如何解决此问题的许多示例已经过时或写得不好,因此我不仅希望完全理解数据流,而且还希望采取清晰,有效的做法。请查看我的方法,如果您觉得我可以做得更好,请告诉我。

假设我要显示“主题”列表,让我们按照到目前为止的过程进行操作。

Amfphp服务

构建并填充了一个名为“ AtlasData”的MySQL数据库后,我开发了我的初始Amfphp服务,该服务使用Amfphp后台服务浏览器似乎返回了一组强类型的“ VoSubject”对象。在我的开发Mac(已安装MAMP)的“ amfphp / Services / vo”文件夹中,我具有以下“ VoSubject.php”文件:

<?php
/**
 * Created by IntelliJ IDEA.
 * User: Chris
 * Date: 04/10/2014
 * Time: 18:31
 */

class VoSubject {

    /* *
     * This Class models one row of the MySQL table. It has one field
     * for each row of the Table and a special extra field.
     * The extra field is $_explicitType, and its value is the fully qualified
     * ActionScript Value Object I intend to use in the Flex application to model the data.
     * If you don‚t configure this field correctly, then in the Flex app you
     * will not get your strongly typed ActionScript class, but a dynamic object.
     * */

    public $subjectId;
    public $subjectName;

    // Explicit ActionScript class
    var $_explicitType = "VoSubject";

}


我的Amfphp服务当前看起来像这样(注意,为了简洁起见,我删除了一些方法):

<?php

require_once ('vo/VoSubject.php');

include ('DbAccess.php');

class AtlasService {

    // This simple function can be used to test the service.
    public function helloWorld() {
        return "Hello World";
    }

    public function getAllSubjects() {

        // Connect to the database using PHP Data Objects (PDO).

        try {

            /*
             * The DbAccess class is a Singleton class.
             * Create an instance of this class to access it's methods.
             */
            $db = DbAccess::getInstance();

            // Create a PHP Data Object.
            $pdo = $db->getPDO();

        } catch (PDOException $e) {

            print "Connection Error!: " . $e->getMessage() . "<br/>";
            die();
        }

        // Retrieve all rows from the AtlasData database 'subjects' Table.
        try {

            $tsql =
                'SELECT s.`subjectId`, s.`subjectName`
                FROM Subjects s';

            $stmt = $pdo->prepare($tsql);
            $stmt->execute();

            // Fetch all of the data and place in variable '$results'.
            $results = $stmt->fetchAll(PDO::FETCH_CLASS, 'VoSubject');

        } catch (PDOException $e) {

            print "Error when fetching data: " . $e->getMessage() . "<br/>";
            die();
        }

        // Close the database connection.
        $stmt = null;
        $pdo = null;

        // Return the array.
        return $results;
    }
}


使用Amfphp后台管理-服务浏览器调用“ getAllSubjects”函数,将返回以下内容:


看来使用代码

$results = $stmt->fetchAll(PDO::FETCH_CLASS, 'VoSubject')


已将$ results设置为VoSubject对象的数组。

弹性应用

因此,现在我希望我的Flex应用程序调用Amfphp服务函数'getAllSubjects。

在开发Flex项目时,我是View Model Presenter的拥护者,我知道它将越来越复杂。在这个项目的初期,我创建了以下内容:

视图-SubjectBar_View(MXML文件)
演示者-SubjectBar_Presenter(ActionScript类)
模型-模型(ActionScript类)

我的SubjectBar_View显示主题列表:

<s:List id="subjectList" dataProvider="{presenter.subjects}">
        <s:layout>
            <s:HorizontalLayout/>
        </s:layout>
        <s:itemRenderer>
            <fx:Component>
                <s:ItemRenderer>
                    <s:HGroup paddingLeft="2">
                        <s:Label text="{data.subjectName}" width="125"/>
                    </s:HGroup>
                </s:ItemRenderer>
            </fx:Component>
        </s:itemRenderer>
    </s:List>


我的SubjectBar_Presenter提供了要绑定到列表的数据源,并且通过在Model中调用方法来设置此属性:

package presenters {

import flash.events.Event;

import models.Model;

import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import vo.VoSubject;

[Bindable]
public class SubjectBar_Presenter {

    private var _model:Model = Model.getInstance();
    private var _subjects:ArrayCollection;

    public function get subjects():ArrayCollection {
        return _subjects;
    }

    public function set subjects(value:ArrayCollection):void {
        _subjects = value;
    }

// Constructor.
    public function SubjectBar_Presenter() {
        // Add an eventListener to listen for property changes in the Model.
        _model.addEventListener("subjectsChanged", onSubjectsChanged);
    }

    private function onSubjectsChanged(event:Event):void {

        // Update the property.
        this.subjects = _model.subjects;
    }

    public function onCreationComplete(event:FlexEvent):void {

        // Get all Subjects from MySQL database.
        _model.getAllSubjects();

    }
}
}


我的模型连接到服务器,并调用Amfphp服务函数'getAllSubjects':

package models {

import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.NetConnection;
import flash.net.Responder;

import mx.collections.ArrayCollection;

// Custom Events.
[Event(name="subjectsChanged", type="flash.events.Event")]

public class Model extends EventDispatcher {

    // Event Names.
    public static const SUBJECTS_CHANGED:String = "subjectsChanged";

    private static var _model:Model;
    private var _subjects:ArrayCollection;
    private var _netConnectionObject:NetConnection;
    private var _responder:Responder = new Responder(handleAllSubjects, null);

    public function get subjects():ArrayCollection {
        return _subjects;
    }

    public function set subjects(value:ArrayCollection):void {
        _subjects = value;

        // Dispatch an event to allow the Detail view to update.
        dispatchEvent(new Event(SUBJECTS_CHANGED));
    }

    public function get netConnectionObject():NetConnection {
        return _netConnectionObject;
    }

    public function set netConnectionObject(value:NetConnection):void {
        _netConnectionObject = value;
    }

    // Constructor.
    public function Model(pvt:PrivateClass) {
        // Call the 'init' function to carry out any preparatory work.
        this.init();
    }

    // Singleton creator.
    public static function getInstance():Model {
        if (Model._model == null) {
            Model._model = new Model(new PrivateClass());
            //trace("Singleton instantiated");
        }
        else {
            //trace("Sorry--already have a Singleton instantiated")
        }
        return Model._model;
    }

    private function init():void {

        // Call any preparatory functions here.
        this.createNetConnection();
    }


    private function createNetConnection():void {

        netConnectionObject = new NetConnection();

        //netConnection.connect( [server name] / [project folder] /amfphp);
        netConnectionObject.connect("http://localhost/amfphp-2.2.1/amfphp/index.php");
    }

    private function handleAllSubjects(result:Object):void{
        // trace(result.toString());

        // The PHP method returns an Array NOT an ArrayCollection.
        this.subjects = new ArrayCollection(result as Array);
    }

    public function getAllSubjects():void {

        // Call the AtlasService.
        //netConnection.call([Service Name]/[function name]", [Responder], [parameters]);
        netConnectionObject.call("AtlasService/getAllSubjects", new Responder(handleAllSubjects, null));
    }

}
}

class PrivateClass {
    public function PrivateClass() {
        //trace("Private class is up");
    }
}


在我的Flex项目的“ src”文件夹中,创建了一个“ vo”文件夹,并创建了以下“ VoSubject”类来定义我的主题值对象:

package vo {
// This is the ActionScript Value Object class.
// This must match the PHP Value Object class defined within the amfphp/Services/vo folder.

[RemoteClass(alias="VoSubject")]
[Bindable]
public class VoSubject {

    public var subjectId:int;
    public var subjectName:String;

    // Constructor.
    public function VoSubject() {
    }
}
}


我不确定在Flex方面是否使用了此VoSubject类。 [RemoteClass(alias =“ VoSubject”)]行是否指向我的amfphp / Services / vo文件夹中的php类?如果是这样,这相对于哪里。是否应该读[RemoteClass(alias =“ vo / VoSubject”)],因为我的VoSubject.php类位于“服务”文件夹中名为“ vo”的文件夹中?

如果我调试我的应用程序,则显示列表,并用subjectNames填充。这很棒。但是,看来我的主题数据源是一个包含SubjectId和subjectName的对象的ArrayCollection,而不是VoSubject对象的ArrayCollection。

有人可以解释一下我如何确保我的“ subjectBar_Presenter”类中的“主题”数据源是强类型VoSubject对象的ArrayCollection。此外,如果您认为我可以改善自己的方法,我也很乐于学习。

谢谢你的结局!我期待着您的想法。

克里斯

最佳答案

var $ _explicitType =“ VoSubject”;应该指向您的动作脚本类,在您的情况下为“ vo.VoSubject”。 [RemoteClass(alias =“ VoSubject”)]应该与显式类型匹配。简而言之,两者都引用了动作脚本类。

乍一看,您的代码似乎遵循MVC模式,这始终很好。但是我必须承认,我快速浏览了所有代码以找到实际的问题。

关于mysql - 使用Amfphp作为Flex的强类型对象获取MySQL数据时的优良作法是什么,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26255816/

10-09 03:51