I've defined a ClientBundle, a Style interface and hooked it up with my css file via the #source annotation.
I have two questions:
when I use <ui:with> in my uibinder file I get the following exception: Deferred binding result type MyStyle should not be abstract. Can someone explain what's going on? And how I can include the style correctly in my uibinder file?
I'd like to share the resource across many uibinder without paying the penalty of initializing the style every time. Gwt's anemic dev guide, suggests using the UiField(provided=true) or using a #uiFactory. Although I've successfully used #uiFactory in order to use my own custom widgets. I have no idea how to use a #uiFactory to inject a style into the uiBinder.
For example:
//in pojo
#UiFactory
public MyStyle getMyStyle() {
return myStyle;
}
//in uibinder
<g:Label addStyleNames="{myStyle.defaultLable}"/>
how can i get this work?
Thanks in advance.
I use the following construction in the uibinder file:
<ui:with field='res' type="com.example.client.resources.MyResource" />
Where MyResource is an interface containing the css resource:
public interface MyResource extends ClientBundle {
#Source("mycss.css")
MyCssResource css();
}
and MyCssResource is:
public interface MyCssResource extends CssResource {
String someStyle();
}
In uibinder file this is used as follows:
<g:TextBox addStyleNames="{res.css.someStyle}" />
Related
From reusabilty point of view, I want to create a component for an interface. So I use it with different concrete objects.
For example, the interface is like this
interface ICalculation
{
double Calculate();
}
and the Test component is
<button #onclick="(() => SetResult())">Set</button>
#result
#code{
double result;
ICalculation Calculation;
void SetResult()
{
result = Calculation.Calculate();
}
}
so some where else in another component/page I have some thing like this
<Test inject CalculationA />
<Test inject CalculationB />
So I want to inject Different Calculations into different instances of this component. How can i get this?
I thought using dependency injection of net core, but that is for to inject one object for an interface.
Why important? It helps me to override requests to api, for example, admin and user have different requests but they see the same page structure.
In the Test component you would make it a normal parameter:
[Parameter]
public ICalculation Calculator { get; set; }
and then in 'some where else'
#inject CalculationA CalculationA
#inject CalculationB CalculationB
<Test Calculator="CalculationA" />
<Test Calculator="CalculationB" />
Or replace those '#inject` lines with normal instantiations (2x) because with multiple implementations you can't do DI on the interface anyway.
I'm using Flex 4.5, and I have imported a custom class I wrote into the main MXML file.
Inside the class file, I want to be able to create a TitleWindow using the PopUpManager like this:
package classes {
import components.*; // My custom components
import mx.managers.PopUpManager;
public class SomeClass {
public function showPopUp():void {
PopUpManager.createPopUp(this,NewProjectPrompt,true);
}
}
}
NewProjectPrompt is a custom component I made. The compiler is giving me the following error:
1067: Implicit coercion of a value of type classes:Project to an unrelated type flash.display:DisplayObject.
This is because this isn't pointing at WindowedApplication. How do I make the first parameter in .createPopUp() point to the WindowedApplication?
this code works!
public function showPopUp(){
PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject,NewProjectPrompt,true);
}
If your WindowedApplication file is named "MyApp.mxml" then you would write a reference from a component to it like this:
MyApp(this.parentApplication)
This will return the actual WindowedApplication and you can call its public methods or stick it in a variable if need be.
Let's say I have an interface
public interface IFoo {
...
}
and I have several implementing classes
public class Foo implements IFoo {
...
}
...
public class Bar implements IFoo {
...
}
...
public class Baz implements IFoo {
...
}
I want to reference IFoo in MXML like this
<ns:IFoo id="myfoo"/>
and have it be instantiated at runtime by a factory.
However, the compiler won't let me do this-- it's trying to do "new IFoo" in the generated ActionScript.
How to get around this? How can I use an interface and a factory purely in MXML?
Declaring an MXML child instantiates an object of that type - you can't simply declare a property in MXML without associating an instance with it.
Given that - there's no way to achieve the equivalent of
public var myFoo:IFoo;
in your MXML.
As James pointed out, you can use a ClassFactory to acheive the following:
<mx:ClassFactory class="{Foo}" id="fooFactory" />
but you would be required to call fooFactory.newInstance() to get an IFoo.
You can implement interfaces in MXML components with the implements="IFoo" attribute in the component's root node.
Edit:
Sorry, I missunderstood your question. I don't know a way to implement a factory in pure mxml. I guess you have to use Actionscript or mxml states to achieve a similar behaviour.
Check out ClassFactory. It is how things like item renderers are instantiated.
This could potentially be a dumb question so apologies in advance if it is.
I'm wondering if theres an equivilant of Interfaces in MXML?
Everytime I feel the need to use an interface I always wind up making an actionscript and not an MXML file because I don't know if / how you can.
For example I was going to have a component based on vbox. I have 4 different implementions of the same thing so I decided to use an interface. But instead of making a single MXML interface and implementing it I've created an interface in as3. I've implemented this interface in 4 different classes.
I then have made 4 different vbox containers each with one of the different implementations in the script tag.
Does this sound like a reasonable approach or am I going against the grain here?
EDIT -- adding examples
The interface
package components.content.contents
{
public interface IContent
{
function init():void;
function doSearch():void
function setSearchTerm(term:String):void
}
}
Implementation (1 of 4)
package components.content.contents
{
public class ClipContent extends AbstractContent implements IContent
{
public function ClipContent()
{
}
public function init():void
{
}
public function doSearch():void
{
}
public function setSearchTerm(term:String):void
{
}
}
}
MXML File (1 of 4)
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">
<mx:Script>
<![CDATA[
// ClipContent Container
import components.content.contents.ClipContent;
public var content:ClipContent= new ClipContent()
public function dostuff():void
{
content.init()
content.doSearch()
}
]]>
</mx:Script>
</mx:VBox>
You can use interfaces with MXML components this way:
// YourClass.mxml
<mx:HBox implements="IYourInterface">
is an MXML equivalent of
// YourClass.as
class YourClass extends HBox implements IYourInterface
But you still need to create the interface (in this example IYourInterface) in Actionscript.
MXML can implement an interface, like Robert Bak said, but it cannot define an interface.
No! MXML is a Declarative language for layout and positioning. By definition it needs an implementation. Interfaces are the definition of an API without an implementation.
It sounds like you're doing things exactly how I would. It is perfectly acceptable for an MXML Component to implement an interface. And it is perfectly acceptable to have multiple components implement the same interface to achieve different results.
For the sake of completeness, an MXML Component can implement an interface just like an ActionScript component ca:
<mx:myComp implements="com.myClass.Interface">
You are correct, there is no way to implement a true interface using MXML(edit: I stand corrected, you can use the "implements" keyword as described in the other answers.) Another approach to consider is to use a "code behind" actionscript file for each of your 4 MXML files:
MXML file (MyFancyVBox.mxml):
<?xml version="1.0" encoding="utf-8"?>
<MyFancyVBoxCode>
...
</MyFancyVBoxCode>
AS file (MyFancyVBoxCode.as):
package com.something.whatever
{
import com.something.another.IFancyInterface;
public class MyFancyVBoxCode implements IFancyInterface
{
...
}
}
The downside is that it doubles the number of source files.
Firstly, I agree with Wade that Code behind may help you.
Secondly, I am thinking do you need the interface in you case. In your question, you want "4 different implementions of the same thing". How about using the "state" in the mxml. It may solve you problems.
I've embedded a MovieClip symbol with the [Embed] syntax into my AS3 project, which I'm compiling with the Flex 3 SDK. That MovieClip has instances of other clips within it that are placed on stage with instance names. I can't just access them by instance name like I would if I were compiling with the Flash IDE.
How can I reference them?
you need to both give them instance names in the IDE and declare them in the class you've embedded them on.
So say that you have instances of baz and frr on your embedded class InfoPopup, you need to declare them like this:
package foo {
import flash.display.Sprite;
[Embed(source='../../../../../../assets/Assets.swf', symbol='InfoPopup')]
public class InfoPopup extends Sprite {
public var baz:Sprite;
public var baz:MovieClip;
public function InfoPopup(){
trace("constructor!");
}
}
}
When added like this they have to be public properties or else the compiler will complain.