Aikau 1.0.66 - Angular 2 Integration

cancel
Showing results for 
Search instead for 
Did you mean: 

Aikau 1.0.66 - Angular 2 Integration

ddraper
Intermediate II
0 15 8,057

Introduction

One of the greatest misconceptions about Aikau is that it is somehow aiming to compete with other UI frameworks and libraries such as Angular and React. This really isn’t the case - Aikau is designed to address specific use cases that no other UI framework meets.

This isn’t trying to say that Aikau is in any way better - it’s just that it can do things that other frameworks can’t. We have integrated other frameworks such as Dojo, JQuery and YUI2 into Aikau - but Angular has been somewhat conspicuous by its absence.

There are a couple of key reasons for this:
 

    1. Angular 1 doesn’t really “play nicely” with other frameworks, although Angular 2 does a much better job of this
    2. Quite honestly there has never been a truly compelling reason to integrate it.


It’s worth remembering the granularity of Aikau widgets and how they are fully decoupled from both each other and the data that they use. Whilst this approach has been key to supporting the dynamic customization use cases, it has not lent itself particularly well to making use of the capabilities that Angular provides.

As you may have heard from recent announcements at BeeCon, Alfresco is looking to start making greater use of Angular 2 for the development of new applications but that it intends to continue to develop Aikau for use in Share.

Recent Announcements

That doesn’t mean that Share is not capable of making use of Angular 2 (or indeed any of the other modern UI frameworks such as React, Ember, etc). In my previous post I showed how modern web development practices could be integrated into Share and in this post I’m going to demonstrate how to make use of some new capabilities available in the 1.0.66 release of Aikau that will allow you to seamlessly insert Angular 2 code into an Aikau page in Share.

One important thing to be aware of… the widget that will be demonstrated resides under a new “alfresco/experimental” package in the Aikau library - anything under this package does not fall into the usual backwards compatibility rules of Aikau and as such maybe changed or removed at any time. If this widget appears useful then you should let us know and we’ll look to make it a fully fledged Aikau widget so that it gets all the backwards compatibility guarantees that this brings.

In this example we’re going to be integrating an example from the Angular 2 tutorial into the faceted search page in Share. Doing so holds no value other than to demonstrate that it can be done.

Step 1. Get Aikau release

First of all, you need to make sure you have downloaded the 1.0.66 release of Aikau and have placed it in the 'share/WEB-INF/lib' folder.

Step 2. Create extension

Now you need to create an extension module for the faceted search page. The quickest way to do this is to follow the steps in this blog post to download an extension JAR file for the faceted search page.

Step 3. Create a package definition

Unpack the JAR file somewhere and edit the the “alfresco/site-data/extensions/extension.xml” file to add in a new AMD package declaration for the Angular 2 tutorial code (background information on defining new AMD packages via extensions can be found in the Alfresco Documentation here.

<extension>
  <modules>
    <module>
      <id>Angular 2 Tutorial Extension</id>
      <auto-deploy>false</auto-deploy>
      <evaluator type='default.extensibility.evaluator'/>
      <configurations>
        <config evaluator='string-compare' condition='WebFramework' replace='false'>
          <web-framework>
            <dojo-pages>
              <packages>
                <package name='blog' location='js/blog'/>
              </packages>
            </dojo-pages>
          </web-framework>
        </config>
      </configurations>
      <customizations>
        <customization>
          <targetPackageRoot>org.alfresco.share.pages.faceted-search</targetPackageRoot>
          <sourcePackageRoot>org.alfresco.share.pages.faceted-search.customization</sourcePackageRoot>
        </customization>
      </customizations>
    </module>
  </modules>
</extension>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Next you want to copy the “main.ts” and “app.component.ts” (these can be copied from here) into the “META-INF/js/blog” folder.

Step 4. Edit the controller extension

Now you want to update the generated JavaScript controller extension ('alfresco/site-webscripts/org/alfresco/share/pages/faceted-search/customization/faceted-search.get.js') to make a dynamic request to add the new Angular 2 widget into the page.

Add the following code into the file:

var verticalStack = widgetUtils.findObject(model.jsonModel.widgets, 'id', 'FCTSRCH_MAIN_VERTICAL_STACK');
if (verticalStack && verticalStack.config && verticalStack.config.widgets)
{
  verticalStack.config.widgets.unshift({
    name: 'alfresco/experimental/ng2/Bootstrap',
    config: {
      main: 'blog/main.ts',
      templateString: '<my-app>Loading...</my-app>'
    }
  });
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The Bootstrap Widget

The widget being added is the “alfresco/experimental/ng2/Bootstrap” widget. The purpose of this widget is to bootstrap the example from the Angular 2 tutorial. Here we are choosing to insert the example above the main search controls.

There are two configuration attributes:
 

    • “main” is the root Angular 2 component to load that should include the call to bootstrap Angular 2 
    • “templateString” is the DOM fragment that contains the custom elements that the Angular 2 component will be looking to parse during bootstrapping.


Once you’ve made these changes you can re-pack the JAR file and copy it to the 'share/WEB-INF/lib' folder.

Restart Share and perform a search. Initially you won’t see anything different - this is because the module has not been applied. More importantly, a second extension module provided by the Aikau JAR is also required.

Step 5. Deploy the modules

Navigate to the Module Deployment page ('/share/page/modules/deploy') and add the “Angular 2 Tutorial Extension” and the “Angular 2 Support (version 1.0.66) module and click the “Apply Changes” button.

Screenshot from 2016-05-03 09:35:54

The “Angular 2 Support” module adds all of the required Angular 2 JavaScript dependencies that are required - most importantly it loads System.js that is used to transpile the TypeScript and handle the ES6 import calls.

Once you have applied these modules you can reload the search page and you’ll see the tutorial example displayed like so:

Screenshot from 2016-04-28 21:23:02

Summary

Obviously this example has no practical purpose whatsoever. However the technique could be used to for much more sensible use cases.

It’s worth noting that, from the moment you bootstrap into an Angular 2 component, you are completely leaving Aikau behind and all future imports should be done via the ES6 import approach as shown in the Angular 2 tutorials.

It’s also important to recognize that this is not suitable for production purposes, because in reality you would want to transpile and compress the Angular 2 code before using it.

If you think the “alfresco/experimental/ng2/Bootstrap” widget would be useful to be made a first class Aikau widget then please let us know - if enough people are interested then we’ll move it to an appropriate package and make it product ready.

Download the Source

You can download the extension module source from this folder in a new GitHub repository that I've setup.

15 Comments
blog_commenter
Active Member
this whole thing seems like a quick shot to me.

is there any good reason why you would not fully ditch aikau?

imo none of the two frameworks are a perfect fit.
ddraper
Intermediate II
@adjin - the reason for not ditching Aikau is because it offers things that Angular 2 (or other frameworks cannot). However, some people might want to extend an Aikau page and with Angular 2 - and this would give them that capability. As explained in the post, it is only a prototype to demonstrate what is possible.
blog_commenter
Active Member
Right now I (as a developer) am just not sure at all if I should dive into aikau.

I can't decide if its worth it.

Especially now where you propose future apps which will be done only in angular (file sharing app).
ddraper
Intermediate II
It's entirely up to you.... but I would say at the time of writing, the Angular 2 based framework mentioned at the BeeCon conference has not yet been created (it is in the early stages of development) and currently there are no other Alfresco provided ECM applications other than Share.



Aikau is still going to be developed and will continue to be used for the development of Alfresco Share. It has always been possible to write clients for Alfresco on top of Surf using any web-framework you'd like, it is also possible to write clients for Alfresco that do not use Surf.



In all cases the question you want to ask yourself is what benefits each framework you want to use will give you. For some, Aikau might have the most benefits (customizations of Share or new clients that have similar capabilities to Share) for others it might be better to build something entirely from scratch.



I can't say what benefits the new framework being developed by Alfresco will bring you because it does not yet exist.
blog_commenter
Active Member
I really like your posts about integration of recent UI technologies. They give me the feeling of hope during the daily fight with YUI 2 and similar stuff. Smiley Wink
blog_commenter
Active Member
Thanks for the response.

This was not meant to be a negative post.

I really appreciate all the good work you guys do. It's just like a jungle sometimes.
blog_commenter
Active Member
Yeah, there are a couple of issues with this approach. One, the lack of a canonical id for the widget means you can only have one Angular widget per page, doesn’t solve the badly behaved library (i.e. jQuery) that will conflict with the global object and doesn’t reuse the AMD dependecy resolution. The main take away as I see it is that by using a different module system (ES6 imports/CommonJS) won’t play nice with Aikau because Aikau _assumes_ that all dependencies are AMD and exposed via the define interface.



I think you've seen the hackathon project I did at BeeCon — https://github.com/rubble/alfresco-share-reactjs — I deliberately ham-fisted in React using the Dojoloader define() inteface such that multiple React widgets are possible and so that Aikau is 'aware' of the widget. Personally, I'd sooner see Alfresco move to using some sort of bundler (Webpack, Browserify) step and then we'd be able to hook config into that sequence rather than at runtime in the browser.
ddraper
Intermediate II
@Emlyn - This isn't supposed to be a definitive solution to the problem, merely an exercise in seeing if something was possible or not. I'm not sure I understand the point about different module systems not playing nicely with Aikau - in this example we're including System.js which can adequately handle the CommonJS, ES6 and AMD module importing. As long as it is included before the Dojo loader is included on the page (I found this out the hard way).



You're right that we have had issues in the past with 3rd party libraries hi-jacking the 'require' function and we have had to avoid those. However we've not had any issue with JQuery.



I'm also not sure I follow why you can't have more than one Angular widget on the page... you can have as many different types of the same AIkau widget on a page as you like, the issue might be with how many times you can bootstrap an Angular 2 Component, but my understanding is that this isn't an issue either (although I could be wrong).



I previously had done another example of nesting Angular 2 based Aikau widgets, but I discarded this approach as it still looked like Aikau (which apparently people don't seem to like, even though it's just JavaScript).



I'm sure that other Alfresco applications will make use of other loader systems, but I realistically can't see this happening in Share (at least not in the short term) but who knows?
blog_commenter
Active Member
Hi Dave,



Instead of having an 'Angular 2 Support' module, that covers the imports for a number of areas including System.js, would it be useful to decompose a bit and pull System.js out by itself so that anything requiring things ES6 support (not just Angular widgets) could use it?



By the way, it's great to see the frequency of these posts over the last while - appreciate they take a lot of time to put together



Steven
ddraper
Intermediate II
Thanks Steven, I think that would make sense for development purposes - however, when it comes to production I would ultimately expect that all JavaScript imports be resolved as part of a prior build process for performance reasons. Having System.js (or anything else) handling transpiling and importing on the fly wouldn't be good for a production system. Ultimately it would be nice if it were not necessary to have it included on the page at all.



Surf has tried to address these issues for some time by aggregating and minimizing JavaScript on CSS on demand and then allowing aggressive caching (both on the server and on the client) to avoid pre-compilation but this doesn't fit with the more recent Node based approaches to this.



Share and Surf is a somewhat niche use case - the ability to dynamically customize pages on the fly. If a developer is in full control of the application then this isn't necessary, but we're trying to relinquish control of the page to a certain extent which is why we jump through these hoops.



As I've said, really, this is just an experiment to prove that something was possible... I'd like to get some Community involvement on where to take these ideas next.
blog_commenter
Active Member
@David, apologies for the tone of the previous post — it was unnecessarily blunt. Your use of UMD with System.js does make sense and I appreciate that this is a proof-of-concept, you openly say that it's not for production.



I was mistaken; you _can_ have multiple Angular widgets on a page. The issue I'm forseeing is that when you put the `` element in your template is that this is processed after the DOM is ready so presumably if you had more than one `` element on the page then you'd have a race condition for a singular instance of AngularJS to transform both. Multiple apps can reside in the page, but the entry point i.e. `` must be different i.e.  ``, `` ... 



I'm pleased that you haven't had a issue with jQuery, the problem that I've encountered if that because Alfresco depends on jQuery 1.6.2 (quite old) is that you have to be careful to set them up in non-conflict mode _and_ if you have a situation where a second library depends on jQuery (quite likely!) then you need to modify the library to use whatever particular jQuery version it requires.
ddraper
Intermediate II
@Emlyn - no need to apologise. I'm happy to receive any feedback as it is always useful. The issue with JQuery is somewhat Share specific and not directly related to Aikau (which imports it's own - much more recent - version of JQuery)... so is more of a Share issue than an Aikau one (although Share obviously is the consumer of Aikau at the moment). Hopefully at some point in the future we'll be able to remove or update that JQuery dependency from Share.



I'm not sure about the race condition scenario - it's not something I've investigated or experienced. Because of the single threaded nature of JavaScript I'd assume that it wouldn't be a major problem. Wouldn't the Angular 2 template be swapped out so only ever parsed once? Again - not something I've looked into yet.



At some point we'll look to provide something more production worthy once Angular 2 is released and will make sure to investigate these types of issues.
blog_commenter
Active Member
[…] Aikau 1.0.66 – Angular 2 Integration […]
velmisoff
Visitor

Hi, Could you explain in detail about step 5. How u get Angular 2 Support (version 1.0.66) module ? I have only Angular 2 Tutorial Extension and i don't see Angular 2 Support (version 1.0.66) 

davidcognite
Senior Member

Hello Oleg Velmisov‌, in your screenshot, it shows Aikau 1.0.63; you need to be on 1.0.66 or higher for this.