使用IntelliJ IDEA 12进行Flex开发 [英] Using IntelliJ IDEA 12 for Flex Development
问题描述
- 不检测组件MXML中的
ID
s。例如,您不能查找组件的ID 。将光标保持在组件的ID上甚至不会标记ID的出现。相反,它在MXML中标记实际的id
单词的出现次数 。 - 极其
我正在认真考虑转移到IntelliJ IDEA 12,特别是在阅读了许多有经验的Flex开发人员的赞叹之后,推荐它。
我试过了。我花了一段时间才弄清IDE的新术语(通过文档和JetBrains非常有帮助的支持人员)。 我能够在IDEA中设置我的(大型)项目Adobe Flex 4.6 SDK,并得到它编译好。但我注意到我的AS文件中突出显示了许多错误,这些错误实际上都是虚假警报。 ActionScript编辑器似乎无法识别MXML中定义的对象。显然,这是IDEA中的一个已知错误(在此处)。 这个错误已经存在了两年多了 引用JetBrains支持人员: 我必须承认突出显示不包含类的ActionScript文件,而是将其作为 恐怕修复不会进入12版本,因为发布很快,修复风险太大。问题的优先级取决于投票和用户反馈。到目前为止,我们只有2票(http://youtrack.jetbrains.com/issue/IDEA-52598),由于修复相当复杂,我们还没有实现它认为这是一个罕见的用例。我希望将它修复到12.x更新版本之一。 我的项目是一个巨大的MXML文件,每个MXML的更大的AS代码。所以,为了组织的目的,我需要从逻辑上将它们分成更小的文件。所以,将AS代码和MXML合并是不现实的。错误突出显示会大大降低代码的可读性。而且,它不允许AS代码中的控制/命令点击组件ID快速导航到MXML中组件的定义(顺便说一句,现在在FB 4.7中也被打破,以及FB 4.6)。 IDEA中的这个错误对我来说是不幸的事情。但我想知道其他的Flex开发人员能够克服/解决这个看似严重的bug。 我觉得只有2人受到影响似乎令人难以置信通过这个bug ,特别是有那么多的Flex开发者推荐IDEA。也许我做错了什么? 所有你的Flex开发者,我将不胜感激你的想法。 这是为了回应RIAStar出色而详细的回答。但这并不完全帮助我。让我解释为什么以及如何使用 我通常将所有的AS代码放在单独的 如果我明白你们是对的,这个事件处理程序代码应该在这些MXML脚本文件中。那么,它应该在哪里呢?你们怎么做?我不确定Spark Skinning体系结构与此有什么关系。 既然我想不出温柔这样做的方式,我会直言不讳:恐怕只有两个人认为这是一个关键的错误,是大多数经验丰富的Flex开发人员会同意使用 后面的代码:许多开发人员使用所谓的代码隐藏模式来将他们的逻辑从他们的视图中分离出来。您可以通过在后面搜索flex代码找到大量关于该主题的信息。一>。我不需要在这里重复这一切。我不太喜欢这个概念,因为它很大程度上依赖于继承,并且两个结果类仍然非常紧密,但至少我们正在讨论两个类。如果你很好的设计你的架构,你甚至可以重用你的一些基类。 b 编写控制器模型:我曾经为每个MXML视图创建一个单独的表示模型类和一个控制器类,然后像这样使用它: MVC纯粹主义者不会喜欢这个,但是在Flex应用程序的上下文中, 使用Flex 4,引入了Spark蒙皮架构,允许非常好地分离视图和逻辑。您可以在普通ActionScript中创建所谓的主机组件类,其中包含所有的行为代码,以及定义组件的可视化表示的MXML中的皮肤类。这使得设计可重用组件变得非常简单。 根据您的要求,下面是一个如何使用Spark皮肤创建注册表单的简单示例。 现在是纯ActionScript的主机组件。它必须扩展 这里有什么重要的东西? 要使用这两个属性类一起: I have been using Flex / Flash Builder for a number of years. The latest release of Flash Builder (4.7) seems to come with quite a few problems, the biggest of those being: I am seriously evaluating moving over to IntelliJ IDEA 12, especially after reading many experienced Flex devs raving about it and recommending it. I tried it. It took me a while to get to terms with the new terminologies of the IDE (made easy by this doc and very helpful support personnel at JetBrains). I was able to setup my (large) projects in IDEA with Adobe Flex 4.6 SDK and got it to compile fine. But I noticed many "errors" highlighted in my AS files which are all actually false alarms. The ActionScript editor doesn't seem to recognise the objects defined in MXML. Apparently, this is a known bug in IDEA (tracked here). And this bug has existed for more than 2 years! Quoting the JetBrains support personnel: I must admit that highlighting of ActionScript files which do not contain classes, but instead included in I'm afraid the fix won't go into 12 release because the release is very soon and the fix is too risky. Priority of the issue depends on votes and user feedback. So far we have only 2 votes (http://youtrack.jetbrains.com/issue/IDEA-52598) and as the fix is pretty complex we still haven't implemented it thinking that this is a rare use case. I hope to fix it in one of 12.x update releases. My project is a huge one, with huge MXML files and even more huge AS code for each MXML. So, for organisation purposes, I need to logically split them into smaller files. So, merging the AS code with the MXML is not practical. The false error highlighting just drastically reduces the readability of the code. Also, it does not allow Control / Command-clicking component IDs in AS code to quickly navigate to the definition of the component in MXML (which, incidentally, is now broken in FB 4.7 as well, but worked well in FB 4.6). This bug in IDEA is unfortunately a deal-breaker for me. But I am wondering how other Flex devs are able to overcome / work around this seemingly critical bug. It seems unbelievable to me that just 2 people have been affected by this bug, especially with so many Flex devs recommending IDEA. Maybe I am doing something wrong? All you Flex developers, I would appreciate your thoughts. This is in response to RIAStar's excellent and detailed answer. But it doesn't quite help me completely. Let me explain why and how I use I usually put all the AS code in separate If I understand you guys right, none of this event handler code should be in these MXML script files. So, where should it be? How do you guys do it? I am not sure how the Spark Skinning architecture has anything to do with this. Since I can't think of a gentle way of putting this, I'll just be blunt: I'm afraid the reason only two people think this is a critical bug, is that most seasoned Flex developers will agree that using So what are your alternatives? Code behind: A lot of developers used the so-called "code behind" pattern to separate their logic from their view. You can find plenty of information on the topic by Googling "flex code behind". I don't need to repeat all that in here. I'm not much of a fan of the concept because it relies heavily on inheritance and the two resulting classes are still pretty tightly coupled, but at least we're talking two classes. If you design your architecture well, you may even be able to reuse some of your base classes. Compose model en controller: I used to create a separate "presentation model" class and a "controller" class for each MXML view and then use it something like this: MVC purists won't like this, but it worked pretty well for me in thencontext of Flex applications. MVC frameworks: My knowledge of this topic is sparse (because in my opinion Flex is a very decent MVC framework that requires no third-party additions, but that's another disussion), but in short: they can help you separate logic from view in a clean way. With Flex 4, the Spark skinning architecture was introduced, which allows for very nicely separated view and logic. You create a so-called 'host component' class in plain ActionScript, which contains all of the behavioural code, and a 'skin' class in MXML which defines the visual representation of the component. This makes designing reusable components very easy. As per your request, here's a simplified example of how you might use Spark skinning to create your signup form. And now the host component in pure ActionScript. It has to extend What's important here? And to use both of these classes together:
这篇关于使用IntelliJ IDEA 12进行Flex开发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
包含在
可能是IntelliJ IDEA代码突出显示的唯一弱点。如果在 mxml
< fx:Script source =some_file.as/> < fx:Script />
的CDATA中嵌入AS代码,而不是引用外部的 *。 / code>文件。虽然我明白,这并不总是想要的。
$ b UPDATE
< fx:Script source>
。我使用了Flex 4.x,几乎只有Spark组件。
$ b .as
文件中,并将其包含在MXML中< fx:Script source>
。这个AS代码通常很重,有很多功能和行为逻辑。很多时候,根据用户的行为,即使MXML中的组件和元素的布局也是通过这个AS代码来修改的。
< fx:Script source =some_file.as/>
是不好的做法。
您可以有效地创建两个代表一个类的文件。从你所关心的可读性POV来看,这不是一个好的举措。其中一个文件(.as文件)只是一堆不能自己存在的函数:它们紧密地耦合到另一个文件/类,但只是查看.as文件,无法知道哪个类它被耦合到。当然,你可以使用某种命名约定来解决这个问题,但最终ActionScript / Flex应该被用作静态类型语言,而不是依赖于混合和命名约定的脚本语言(不要误解我的意思:我并不是说脚本语言是不好的做法,它不是如何构思ActionScript的。)
我想这个构造背后的主要原因是您希望将MXML从ActionScript代码中分离出来,或者更抽象地说:将视图从逻辑中分离出来。幸运的是,这可以通过其他一些更简洁的方式来实现。您可以使用哪些解决方案取决于我们是在讨论Flex 3(或更早版本)还是Flex 4.
我意识到您可能没有时间将代码重构为其中一种建议的解决方案,但是我没有想要给你留下一个不好的做法的答案。
Flex 3(mx)
$ b
<! - MyView.mxml - >
< mx:VBox>
< m:MyModel id =model/>
< c:MyController model ={model}view ={this}/>
...
< / mx:VBox>
稍后当支持框架(如Parsley)的直接注入支持框架出现时,我可以使用注入来连接所有这些类,而不是像这个例子那样硬连线。 MVC框架:我对这个主题的知识是稀疏的(因为在我看来,Flex是一个非常体面的MVC框架,不需要第三方添加,但是这是另外一个讨论),但总之,它们可以帮助你以一种干净的方式从视图中分离逻辑。
Flex 4(Spark)
让我们从皮肤类开始,因为它很容易理解。这只是一个有一些输入字段的表单。 HostComponent
元数据告诉皮肤它应该与注册主机组件一起工作。
<! - SignUpSkin.mxml:可视化表示 - >
xmlns:s =library://ns.adobe.com/flex/spark >
< fx:元数据>
[HostComponent(net.riastar.view.SignUp)]
< / fx:Metadata>
< s:表格>
< s:FormHeading label =注册/>
< s:FormItem label =用户名称>>
< s:TextInput id =userInput/>
< / s:FormItem>
< s:FormItem label =Password>
< s:TextInput id =passwordInputdisplayAsPassword =true/>
< / s:FormItem>
enabled ={hostComponent.canSave}/>
< / s:表格>
< / s:Skin>
SkinnableComponent
才能使用我们的皮肤(还有 SkinnableContainer
,我刚刚解释过这个问题:Flex MXML定制组件 - 如何添加组件
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;
覆盖保护函数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
的变量将自动被赋予与Skin中存在的id相同的组件创建。例如< s:TextInput id =userInput/>
将被注入到 public var userInput:SkinnableTextBase;
。请注意,类型是不同的: SkinnableTextBase
是 TextInput
的基类。这使得我们可以用例如一个 TextArea
,而不是一个 TextInput
,它将工作,而不接触主机组件。
每当将SkinPart添加到显示列表中时,调用 partAdded()
,这就是我们连接事件监听器的地方。在这个例子中,我们验证用户名,只要其值改变。
验证完成后,您可以简单地将 canSave
属性设置为 true
或 false
。这个属性的皮肤绑定将自动更新Button的 enabled
属性。
< v:SignUp skinClass =net.riastar.skin.SignUpSkin/>
ID
s in MXML. For example, you cannot Find Usages of the ID of a component. Keeping the cursor on the ID of a component does not even mark occurrences of the ID. Instead, it marks occurrences of the actual id
words in the MXML.
mxml
as <fx:Script source="some_file.as"/>
is probably the only weak part of IntelliJ IDEA code highlighting. False error highlighting will go away if you embed AS code inside CDATA of <fx:Script/>
instead of referencing as external *.as
file. Though I understand that this is not always desired.UPDATE
<fx:Script source>
. I am using Flex 4.x, with almost only Spark components.
.as
files and include it in the MXML using <fx:Script source>
. This AS code is usually quite heavy, with a lot of functional and behavioural logic. Many times, based on user action, even the components in the MXML and layout of the elements is modified through this AS code.<fx:Script source="some_file.as"/>
is bad practice.
You effectively create two files that represent one class. From a readablity POV, which you seem concerned about, that's not a good move. One of these files (the .as file) is just a bunch of functions that cannot exist in their own right: they are tightly coupled to another file/class, but just looking at the .as file there is no way of knowing which class it is coupled to. Of course you can use some kind of naming convention to work around this, but in the end ActionScript/Flex is supposed te be used as a statically typed language, not a scripting language relying on mixins and naming conventions (don't get me wrong: I'm not saying scripting languages are bad practice; it's just not how ActionScript was conceived).
I suppose the main reason behind this construct is that you wish to separate MXML from ActionScript code, or in more abstract terms: separate the view from the logic. Fortunately this can be achieved in a few other, cleaner ways. Which solutions are available to you depends whether we're talking Flex 3 (or earlier) or Flex 4.
I realise that you may not have time to refactor your code to one of the proposed solutions, but I didn't want to leave you with just a "that's not good practice" answer.Flex 3 (mx)
<!--MyView.mxml-->
<mx:VBox>
<m:MyModel id="model"/>
<c:MyController model="{model}" view="{this}"/>
...
</mx:VBox>
Later when Direct Injection supporting frameworks (like Parsley) made their appearance, I could use injection to wire all those classes instead of hard-wiring them like in this example.Flex 4 (Spark)
Let's start with the skin class since it's easy to understand. It's just a form with some input fields. The HostComponent
metadata tells the skin it's supposed to work together with the SignUp host component.<!--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>
SkinnableComponent
to be able to use our skin (there's also SkinnableContainer
which I've just recently explained in this question: Flex mxml custom component - how to add uicomponents?, but we won't be needing that here).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);
}
...
}
The variables marked as SkinPart
will automatically be assigned the components with the same id that exist in the Skin you just created. For instance <s:TextInput id="userInput"/>
will be injected into public var userInput:SkinnableTextBase;
. Note that the type is different: SkinnableTextBase
is the base class of TextInput
; this allows us to create another skin with e.g. a TextArea
instead of a TextInput
and it'll work without touching the host component.
partAdded()
is called whenever a SkinPart is added to the display list, so that's where we hook up our event listeners. In this example we're validating the username whenever its value changes.
When the validation is done, you can simply set the canSave
property to true
or false
. The binding in the skin on this property will automatically update the Button's enabled
property.<v:SignUp skinClass="net.riastar.skin.SignUpSkin"/>