繁体   English   中英

使用IntelliJ IDEA 12进行Flex开发

[英]Using IntelliJ IDEA 12 for Flex Development

我已经使用Flex / Flash Builder多年了。 Flash Builder(4.7)的最新版本似乎存在很多问题,其中最大的问题是:

  • 不检测MXML中的组件ID 例如,您无法找到组件ID的用法 将光标停留在组件的ID上甚至不会标记该ID的出现。 而是在MXML中标记实际id字的出现。
  • 极为缓慢。

我正在认真评估迁移到IntelliJ IDEA 12的过程,尤其是在阅读了许多有经验的Flex开发人员对此的好评和推荐之后。

我尝试过这个。 我花了一些时间来了解IDE的新术语( 文档使它变得容易,并且JetBrains的支持人员非常乐于助人)。

我能够使用Adobe Flex 4.6 SDK在IDEA中设置我的(大型)项目,并使它可以正常编译。 但是我注意到AS文件中突出显示的许多“错误”实际上都是错误的警报。

ActionScript编辑器似乎无法识别MXML中定义的对象。 显然,这是IDEA中的一个已知错误( 在此跟踪)。 这个错误已经存在了2年多了!

引用JetBrains支持人员:

我必须承认,不包含类但以<fx:Script source="some_file.as"/>形式包含在mxml的ActionScript文件突出显示可能是IntelliJ IDEA代码突出显示的唯一弱项。 如果将AS代码嵌入<fx:Script/> CDATA中而不是引用为外部*.as文件,则错误高亮显示将消失。 尽管我知道这并不总是需要的。

恐怕此修复程序不会发布到12版本中,因为该版本发布很快,而且修复风险太大。 问题的优先级取决于投票和用户反馈。 到目前为止,我们只有2票(http://youtrack.jetbrains.com/issue/IDEA-52598),并且由于此修复程序非常复杂,我们仍未实现它,认为这是一种罕见的用例。 我希望在12.x更新版本之一中修复它。

我的项目是一个巨大的项目,具有巨大的MXML文件,甚至每个MXML都有更大的AS代码。 因此,出于组织目的,我需要将它们逻辑上分成较小的文件。 因此,将AS代码与MXML合并是不切实际的。 错误的高亮显示会大大降低代码的可读性。 而且,它不允许AS代码中的Control / Command单击组件ID来快速导航到MXML中的组件定义(顺便说一句,现在在FB 4.7中也被破坏了,但是在FB 4.6中运行良好)。

不幸的是,IDEA中的这个错误对我来说是一个破坏交易的行为。 但是我想知道其他Flex开发人员如何能够克服/解决这个看似关键的错误。

在我看来,只有2个人受到此错误的影响 ,尤其是这么多Flex开发人员推荐IDEA的时候。 也许我做错了什么?

各位Flex开发人员,我将不胜感激。

更新

这是对RIAStar出色而详尽的回答的回应。 但这并不能完全帮助我。 让我解释为什么以及如何使用<fx:Script source> 我正在使用Flex 4.x,几乎只有Spark组件。

  • 假设一个全新的Flex项目。 主要应用程序是一个MXML文件。
  • 在这个MXML文件中,假设我有一个注册表单。
  • 在编辑表单时(在每个字段中),假设我必须运行验证并仅在表单完全有效时启用“ 提交”按钮。 这意味着我需要将变更事件处理程序分配给表单项。 事件处理程序是AS代码。
  • 假设有一个用户名字段,需要通过异步调用服务器来进行类型唯一性检查。 服务器通信代码也是AS代码。
  • 然后当然还有“ 提交”按钮处理程序,它也是AS代码。

我通常将所有AS代码放在单独的.as文件中,并使用<fx:Script source>将其包含在MXML中。 该AS代码通常很重,具有许多功能和行为逻辑。 很多时候,基于用户操作,甚至MXML中的组件和元素的布局也可以通过此AS代码进行修改。

如果我理解的没错,那么这些MXML脚本文件中都不应包含此事件处理程序代码。 那么,应该在哪里? 你们是如何做到的? 我不确定Spark Skinning架构与此有关。

由于我想不出一种温和的方法,因此我会直言不讳:恐怕只有两个人认为这是一个严重的错误,原因是大多数经验丰富的Flex开发人员都会同意使用<fx:Script source="some_file.as"/>是错误的做法。
您可以有效地创建代表一个类的两个文件。 从您似乎关注的可读取性POV来看,这不是一个好举动。 这些文件中的一个(.as文件)只是一堆无法单独使用的函数:它们与另一个文件/类紧密耦合,但是仅查看.as文件,就无法知道哪个类它耦合到。 当然,您可以使用某种命名约定来解决此问题,但最终应该将ActionScript / Flex用作静态类型的语言,而不是依赖于mixin和命名约定的脚本语言(不要误解我的意思) :我并不是说脚本语言是坏习惯;这不是ActionScript的构思。

那么您有什么选择?
我想这种构造背后的主要原因是,您希望将MXML与ActionScript代码分开,或者更抽象地讲:将视图与逻辑分开。 幸运的是,这可以通过其他几种更清洁的方式来实现。 可用的解决方案取决于我们使用的是Flex 3(或更早版本)还是Flex4。我意识到您可能没有时间将代码重构为建议的解决方案之一,但是我不想离开您仅给出“这不是好习惯”答案。

Flex 3(MX)

背后的代码:许多开发人员使用所谓的“背后的代码”模式将其逻辑与视图分离。 您可以通过谷歌搜索“ flex背后的代码”找到有关该主题的大量信息。 我不需要在这里重复所有这些。 我不太喜欢这个概念,因为它在很大程度上依赖于继承,并且两个生成的类仍然紧密耦合,但是至少我们在谈论两个 如果您对架构进行了良好的设计,您甚至可以重用一些基类。

编写控制器模型:我曾经为每个MXML视图创建一个单独的“表示模型”类和一个“控制器”类,然后使用如下代码:

<!--MyView.mxml-->
<mx:VBox>
    <m:MyModel id="model"/>
    <c:MyController model="{model}" view="{this}"/>
    ...
</mx:VBox>

MVC纯粹主义者不喜欢这样,但是在Flex应用程序的背景下,它对我来说非常有效。
后来当Direct Injection支持框架(如Parsley)出现时,我可以使用Injection来连接所有这些类,而不是像本例中那样硬接线。

MVC框架:我对此主题的了解很少(因为我认为Flex是一个非常不错的MVC框架,不需要第三方添加,但这是另一种争议),但总之:它们可以帮助您将逻辑从视图中分离出来。干净的方法。

Flex 4(火花)

在Flex 4中,引入了Spark外观皮肤架构,该架构允许将视图和逻辑很好地分离。 您可以在普通的ActionScript中创建一个所谓的“宿主组件”类,其中包含所有行为代码,而在MXML中创建一个“皮肤”类,它定义了组件的外观。 这使得设计可重复使用的组件非常容易。

根据您的要求,这是一个简化的示例,说明如何使用Spark外观创建注册表单。
让我们从皮肤类开始,因为它很容易理解。 它只是带有一些输入字段的表单。 HostComponent元数据告诉皮肤它应该与SignUp主机组件一起使用。

<!--SignUpSkin.mxml: the visual representation-->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Metadata>
        [HostComponent("net.riastar.view.SignUp")]
    </fx:Metadata>

    <s:Form>
        <s:FormHeading label="Sign up"/>

        <s:FormItem label="User name">
            <s:TextInput id="userInput"/>
        </s:FormItem>

        <s:FormItem label="Password">
            <s:TextInput id="passwordInput" displayAsPassword="true"/>
        </s:FormItem>

        <s:Button id="submitButton" label="Submit" 
                  enabled="{hostComponent.canSave}"/>
    </s:Form>

</s:Skin>

现在是纯ActionScript中的宿主组件。 它必须扩展SkinnableComponent才能使用我们的皮肤(还有我最近在此问题中解释过的SkinnableContainerFlex mxml自定义组件-如何添加uicomponents ? ,但我们在这里不需要。)

public class SignUp extends SkinnableComponent {

    [SkinPart(required="true")]
    public var userInput:SkinnableTextBase;

    [SkinPart(required="true")]
    public var passwordInput:SkinnableTextBase;

    [SkinPart(required="true")]
    public var submitButton:IEventDispatcher;


    [Bindable]
    public var canSave:Boolean;


    override protected function partAdded(partName:String, instance:Object):void {
        super.partAdded(partName, instance);

        switch (instance) {
            case userInput:
                userInput.addEventListener(TextOperationEvent.CHANGE, 
                                           handleUserInputChange);
                break;
            case passwordInput:
                passwordInput.addEventListener(TextOperationEvent.CHANGE, 
                                               handlePasswordInputChange);
                break;
            case submitButton:
                submitButton.addEventListener(MouseEvent.CLICK, 
                                              handleSubmitButtonClick);
        }
    }

    private function handleUserInputChange(event:TextOperationEvent):void {
        validateUsername(userInput.text);
    }

    ...

}

这里重要的是什么?
标记为SkinPart的变量将被自动分配与您刚创建的外观中存在的ID相同的组件。 例如, <s:TextInput id="userInput"/>将被注入到public var userInput:SkinnableTextBase; 注意类型是不同的: SkinnableTextBaseTextInput的基类; 这使我们可以使用TextArea而不是TextInput创建另一个外观,并且无需触摸宿主组件即可工作。
每当将SkinPart添加到显示列表时,都会调用partAdded() ,因此我们可以在此处挂接事件监听器。 在此示例中,每当用户名的值更改时,我们就对其进行验证。
验证完成后,您可以简单地将canSave属性设置为truefalse 此属性在皮肤上的绑定将自动更新Button的enabled属性。

并一起使用这两个类:

<v:SignUp skinClass="net.riastar.skin.SignUpSkin"/>

实际上,我已经非常喜欢使用RobotLegs。

在我的MXML视图中,我尝试将所有逻辑保留在MXML之外,而只是将事件分发给中介。 从那里,我可以将代码放入中介器中,以放置所需的更重的AS。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM