The app part communication framework has been created to overcome the restrictions that the use of iframes in app parts imposes and makes use of the benefits of having control over the master page when developing in SharePoint Online for a company intranet.
Its current state is the result of a couple weeks of on and off contemplation and a few hours of development - thus it is still in its early stages and is going to be expanded upon (and used in a production environment) and so I will revisit this post and update it accordingly.
The latest SharePoint announcements regarding upcoming changes later this year/next year should overcome the issue I am trying to solve here, so the timing of this is rather ironic, but I still feel that this framework is worth posting about, not least because I can point the development and support team to it.
As solution architect on a new project (and solution architect on the previous project with the same customer) I am trying to find a way to create a practical coding approach to using app parts in a responsive design-based content management system. Our previous portal (not responsive design) implementation contained numerous heavy-handed farm solution-based customisations and all of these need to be part of the new template-based portal which must ideally fit within the app model so that if/when we move to SharePoint Online, there is minimal effort required. Thus my intent is to completely avoid the use of farm solutions.
The new project is aimed at providing responsive design-based reusable SharePoint site template(s) that can offer the same easy-to-use web parts (tiles, carousels, custom media, etc.) that are in the existing portal - but of course, these need to be app parts. In creating these parts, our UI designer is currently creating these inline rather than in app parts and so I really wanted to provide a way to have the flexibility of an editor choosing to add parts to the page while editing but have the rendering happen in the main page, outside the iframe. This meant that there would need to be a way for the app part's iframe to communicate about the app part to the main page and allow the main page to do the rendering.
Firstly, this is in the very early stages of development but please feel free to suggest any changes/improvements in the approach taken or any of the coding methodology.
I will add diagrams at a later point but for now I am writing this up quickly so it can be used by the team.
The basic structure is this:
- APCF.js - resides in provider hosted website
- APCF[app part type].js e.g. APCFAppPartExample1.js - resides in the provider hosted website
- Provider-hosted app part - contains inline script that calls postMessage
- JS Objects
- The APCF object is an object initialised using literal notation and comprises a few methods for processing message and registration of app parts
- The APCFAppPartType object is used to describe an object type identifier - each app part registers itself as an app part type
- The APCFAppPartInstance is a base object from which each type of app part inherits a class (using the 'apply' method). Each of these inheriting instance classes are the identified in the APCFAppPartType object
- This base object has a flow of execution upon registration: initialise, load, render
- Each of these is declared in the base object as a "_base" so initialise_base, load_base, render_base - and each of these methods first calls the respective methods (initialise, load, render) then calls the next base method
- This means that if an instance implements the initialise, load or render methods then they will be called in that order automatically
The basic flow is this:
- Main page loads jQuery
- Main page loads the APCF.js file which comprises:
- APCF declaration
- APCFAppType declaration
- APCFAppInstance declaration
- Registers onmessage event to call APCF.processMessage
- Each app part aspx loads jQuery and APCF.js and the relevant App Part Type JS file and register the APCF.processMessage to handle APCF events
- On load, app part uses postMessage to send a serialized object (currently manually created but should be wrapped)
- postMessage is picked up by APCF.processMessage running within the main page, deserializes the object and checks the messageType property
- A switch statement calls the relevant APCF method depending on the messageType
- The first call from the app part registers the App Type which contains the App Part Type registration information (including script URL)
- This causes the APCF to call the iframe back using postMessage to say the app type has been registered
- On handling the registration, the app part ASPX then registers the instance
- Registratioin of the instance causes the APCF to start rendering
The code is available from the URL above. Please feel free to comment. I will add documentation to the codeplex site ASAP