使用Amfphp作为Flex的强类型对象获取MySQL数据时的良好实践是什么?

时间:2014-10-08 11:29:02

标签: mysql flex amfphp

我正处于为新项目设置架构的早期阶段。数据驱动的Flex UI,位于网页中,调用Amfphp Service for MySQL数据来填充Flex UI中的元素。

如此处理这么多的例子已经过时或写得不好,所以我不仅要完全理解数据流,还要建立清晰,稳健的实践。请检查我的方法,如果您觉得我可以做得更好,请告诉我。

我想要显示一个“主题列表”,让我们按照目前的流程进行操作。

Amfphp服务

我已经开发了一个名为' AtlasData'的MySQL数据库,我已经开发了我最初的Amfphp服务,它使用Amfphp后台服务浏览器,似乎返回了一个强类型的数组&#39 ; VoSubject'对象。在我的amfphp / Services / vo文件夹中的我的开发Mac(安装了MAMP)上,我有以下' 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后台 - 服务浏览器调用&#39; getAllSubjects&#39;函数返回以下内容: Amfphp Back Office - Service Browser Result

似乎使用代码

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

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

Flex应用程序

所以现在我希望我的Flex应用程序调用Amfphp Service函数&#39; getAllSubjects。

在开发Flex项目时,我是View Model Presenter的拥护者,我知道这些项目的复杂性会升级。在这个项目的初期,我创建了以下内容:

views - SubjectBar_View(MXML文件) 演示者 - SubjectBar_Presenter(ActionScript类) model - Model(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>

My SubjectBar_Presenter提供要绑定的List的数据源,并通过调用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服务功能&#39; getAllSubjects&#39;:

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项目&#39; src&#39;文件夹我创建了一个&#39; vo&#39;文件夹并创建了以下&#39; VoSubject&#39;用于定义主题值对象的类:

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 =&#34; VoSubject&#34;)]是否指向我的amfphp / Services / vo文件夹中的php类?如果是这样,这相对于哪里。它应该是[RemoteClass(别名=&#34; vo / VoSubject&#34;)],因为我的VoSubject.php类位于一个名为&#39; vo&#39;在我的服务文件夹中?

如果我调试我的应用程序,将显示List并使用subjectNames填充。这很棒。但是,我的主题数据源似乎是包含subjectId和subjectName但不包含VoSubject对象的ArrayCollection的对象的ArrayCollection。

有人可以解释一下我如何确保我的主题&#39;我的主题栏中的数据来源:#Bar_Presenter&#39; class是强类型VoSubject对象的ArrayCollection。另外,如果你觉得我可以改进我的方法,我非常愿意学习。

感谢您走到尽头!我期待着你的想法。

克里斯

1 个答案:

答案 0 :(得分:1)

var $ _explicitType =&#34; VoSubject&#34;; 应指向您的actionscript类,在您的情况下&#39; vo.VoSubject &# 39 ;. [RemoteClass(alias =&#34; VoSubject&#34;)] 应与显式类型匹配。简而言之,两者都引用了actionscript类。

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