Open flexicious opened 6 years ago
Check out how Ace Editor is available in Royale. There is a frameworks/projects/Ace SWC and an examples/royale/Ace example. Yishay can probably provide more details.
As well, Material Design Lite is an example of wrapping an existing js/css component library in Royale. Check the MDL library SWC.
Another option is to use a JS lib directly like in this example:
That uses HighlightCode class here:
that wraps this js library:
HTH
Wow @carlosrovira great to hear that you were able to utilize my code for highliting code! Thank you! :)
Hi Piotr, hehe, thought you already see that! :) I still need to make the same use in the rest of Jewel Example, but I'm with very few time this days... hope to do so as I can so we can hang JewelExample in the website soon to showcase the UI Set that is now mostly in production state ;)
Ok this is great, so let me delve specifically into what we're trying to do, and whether its even possible. We have a HTML based datagrid component, originally written for Flex, but we ported to HTML. http://htmltreegrid.com/ . IT takes markup like
<grid ... itemClick="functionDefinedInActionScript" ... ><level ><columns><column columnLockMode="left" dataField="investor" ... /> ... </columns></level></grid>
or a JSON object similar to above, except itemClick would point to a function { itemClick : functionDefinedInActionScript }
the grid then either evals "functionDefinedInActionScript" if you pass in a string or references it directly if you pass in a function.
So the question is, is there a way I can define functionDefinedInActionScript and then the grid "knows" to call it? I would bind it to this before passing it in functionDefinedInActionScript.bind(this)
Second question, the grid has an extensive API. So how would i go about calling lets say
grid.rebuild() or grid.setDataProvider()?
Based on your description above, it should be possible. I want to point out that having any "multi-type" APIs is not recommended when using strongly-typed languages, so having a property that takes either a String or a Function is not a best practice.
Also, for folks coming from the Flex world, having an attribute named "itemClick" that isn't an event handler will also be unexpected and cause confusion.
So, you have some choices: 1) to exactly reproduce your multi-type API, you would define: public var itemClick:Object;
The problem with doing this is that: A) folks could pass a Number and the compiler will not care B) If folks pass a method, the compiler will not know to convert it to a closure (bind 'this')
2) You could define 2 properties: public var itemClick:Function; public var itemClickFunctionName:String;
Users would assign one or the other. The compiler will generate closures for methods assigned to itemClick because it is now of type Function.
3) Wrap the grid and have it dispatch an Event.
This will make it work just like Flex. The Grid won't have to callback anything per-se. The wrapping code would always assign itemClick to some function that dispatches an Event. I would recommend this pattern.
I'm not sure I understand your second question. If you are asking how to make your JS component available in MXML, the answer is that MXML is oriented towards getter/setters (which map to Object.defineProperties() in JS). So the dataProvider setter would call your setDataProvider method.
Maybe some context might help here This is for a HTML port of our Flex product (Which is essentially the flex DataGrid with a lot of bells and whistles)
itemClick is actually not a property, its a event type that we defined in our HTML component. When we ported our code from Flex to HTML, we wrote our own DisplayObject, EventDispatcher, UIComponent etc. so itemClick in this context is the exact same thing we had in Flex, an event defined on a DataGrid. When you pass in that in config, we translate it to this.addEventListener("itemClick", functionYouPassedIn). Think of our XML (or JSON) config as an alternative to MXML that does not exist on the HTML side.
But that said - is there an example that does sorta what you describe above?
And for the second part in regards to the question about grids api. The JS component we have an extensive API - just like the Flex Datagrid did. I looked at your aceeditor here: https://github.com/apache/royale-asjs/blob/bdd5e07aae1e5e9f22cee9f38c19f04a281572f7/frameworks/projects/Ace/src/main/royale/org/apache/royale/ace/ACEEditor.as
Im a bit confused about editor = ace"edit"; --> Is "ace" here defined on the window object? What is id?
Second, public function set theme(value:String):void { _theme = value; editor.setTheme(value); }
If I am understanding this, editor is the JS object the third party library creates, and setTheme is a method on it that this wrapper is calling when royale executes the theme setter. We have hundreds of such methods, is there a way to ask royale to just marshall all calls like setDataProvider, setColumns etc to the underlying JS object? OR may be I am misunderstanding what this is.
First a side-comment: I'm sure you have finished your port to HTML/JS, but keep in mind that with Royale you can develop your JS code in AS and gain the benefits of strict type-checking at compile-time.
OK, so I thinK i now understand the markup you showed above. If you add Event metadata like in Flex to the AS class that represents your component, then the Royale compiler will set up the call to addEventListener and bind 'this' to the appropriate object. You'll see that most Royale components have Event metadata on them. Ace doesn't, but MaterialDesignLite does.
In the Ace example, Ace is the object set up by loading the JS code for the Ace Editor.
I don't think anyone has tried using an unwrapped JS component in Royale. It is theoretically possible and I and hopefully others would be willing to help make it work. The reasons we've wrapped everything so far is to avoid touching the 3rd-party code since we don't control the source for it. Similar to Flex and IUIComponent/IFlexDisplayObject, all Royale UI widgets must implement IUIBase. So if you are willing to modify your code or subclass your JS grid to implement IUIBase, then you have a shot at making it work. And you may need to add getter/setters, and metadata. And then you may expose some bugs we have where we are assuming UIBase instead of IUIBase, but those are things we want to find and fix.
Fundamentally, Royale is less of a framework and more of a workflow for integrating existing chunks of JS. We have some required contracts like IUIBase so we have a common way to size and position UI widgets from different providers, but otherwise, we are trying to have few "must haves".
Yep - we finished the port back in 2012 . The port has been in production for a large number of our Flex customers who moved on to HTML. We also wrote a React Port in ES6, iOS port in Objective C, Android Port in Java, integrations with Bootstrap, Angular, jQuery, even EXT and Dojo - Its amazing how similar all these UI architectures are. But I digress.
"So if you are willing to modify your code or subclass your JS grid to implement IUIBase" Our code is JAvaScript. isnt IUIBase ActionScript? OR do you mean modify our original ActionScript code - but thats peppered with Flash Player API.
In either case, the customer here who wants to explore royale would need to use third party components other than our grid that they dont have access to the source code for - like charting libraries, autocomplete components, calendar components - they dont need the swf target. Am I correct in assuming that as of now, there is no easy way of doing this in Royale? Like is it possible to throw up a highcharts pie chart on a screen, and then have a Royale Material Lite button click and refresh it, and then also listen for a click handler on the chart and have royale open up a Material popup from the pie slice clicked on?
IUIBase source code (and all Apache Royale component source) is in ActionScript, but eventually is transpiled to JS. So, to have your JS code implement IUIBase, you would need to add the equivalent JavaScript to your code or a subclass of it. Or write the subclass in AS and have it transpiled. Methods are not checked right now, only classes, so it shouldn't be too hard.
You can easily skip the SWF target. MaterialDesignLite doesn't support a SWF target right now.
How you assemble a bunch of third-party components from different vendors in Royale depends on how those components work and how you want to write your code.
To use MXML, you need a certain amount of infrastructure, like an Application class that supports certain APIs.
Whether you use MXML or AS, if you want to use Royale containers and layouts then you need the components to support IUIBase.
Some 3rd-parties have interesting ways of instantiate components like creating HTML markup and identifying it in the JS. ActionScript is mainly built around using the "new" operator and calling functions and so Royale has not invested in trying to find objects from HTML markup.
So, to the extent that you can use little or no HTML and a pile of JavaScript to create this app for your customer, you should be able to use AS instead of JS, and get the benefits of compile-time type-checking (assuming you make the 3rd-party APIs strongly-typed via typedefs/externs).
You could then just use MaterialDesignLite components instead of the Royale versions. But is that really "using Royale"? You are just replacing JS with AS. If you want Royale containers and layout you need to implement IUIBase on those components, but you don't have to worry about the SWF target.
If someone has a huge Flex app using Flexicious Grid, the way to migrate them off of Flash with the least changes to their code is to use the emulation components and present any 3rd-party JS components as IUIComponents instead of IUIBase because the emulation components are purposefully presenting a Flex-like API. But again, you can do that without worrying about the SWF side and in the end, there should be tons fewer lines of code to debug. Their business logic should be relatively untouched.
We are trying out royale, and I was wondering can I put highcharts (or any other third party javascript component) within royale? Is there a sample?