• PRODUCT

    PRODUCT

  • PRICING
    PRICING

  • HELP
    HELP

  • BLOG
    BLOG

  • APPSTORE
    APPSTORE

  • COMPANY
    COMPANY

  • LEGAL
    LEGAL

  • LOGIN
    LOGIN

  • How do splitters, slides and frames work


  • In this article we will discuss how you can use splitters, slides and frames to build reusable marketing flows that can be leveraged in your marketing campaigns


  • Introduction

    Izy Circus enforces an architectural design paradigm on the developers that would allow:
    • Parameterized path matching and state management so that the UI state can be configured directly by the URI.
    • Mosaic form of UI development that breaks up the build of deep hierarchies and parent-child relationships and forces the pieces to communicate through the frames (grout).
    • Framized UI component architecture that groups and contextualizes the interactions between parts.

    Clonable vs Referencable components

    Referencable components are things that will be used by:

    • referencing the original library by importing the library into an app
    • passing configuration to the components.
    It is the most commonly used in legacy software development: The behvaior is customizaed via passing in configuration without changing the component.

    Clonable components are things that will be used by:

    • Cloning (copying) their source code into a new container
    • Customizing the new container

    Metaphorically speaking, if the app was mosaic art, clonable components would be the grout while the referencable components would be mosaic or parts of the mosaic that gets woven together using clonable components.

    There is a good reason for this distinction. Clonable components usually embed user and business flows and processes that need visual cutomizations and change very often. This fact makes them a poor choice for reusability. On the other hand referencable components typically

    Client Side UX components

    • Navigation Frame Definition
    • Slides
    • Frames
    • Embeddable Parts

    Navigation Splitter

    Their main purpose is to:
    • define mapping between navItems and slides by:
    * ext referencing a frame (i.e. frame/minimal)

    * calling frame_setnav on the part

    • provide a bridge between the slides hosted and their peer slides

    * defining 'frame_notify' event

    * picking doChain or the implicit chain from the notify to communicate between their own slides and peer slides/
    • may provide the common UX that all the slides would share (i.e. bread crums, back button, etc.)
    • provide isolation between the parent context and slides context

    * The uri changes that match only the navItems for the splitter will only trigger refresh.

    Slides

    • Slides are the parts that are designated by the splitter to handle specific nav configuration.
    • Slides (and all their subcomponents) are created and destroyed every time a frame_nav event occurs.
    • Typically for every visible user state change, a new slide should be defined.
    • Slides can and will have subcomponents and ui parts. While their sub components can be organized as hierarchies of components and all their children could still launch 'frame_xxx' commands without having to be aware of their place in the hierarchy. This is key and allow for a flat and mosaic like component organization: all elements can communicate with the reference frame independeny of organization.
    • Slides are the building blocks of the Frames. The framework by design enforced a paradigm that removes any visual dependency between the slides. This is meant to simplify the development. In contrast, subcomponents whithin slides may be visually dependent (i.e. grid selection and context menu) and need synchronization. To accomplish this the slide would need to implement a transition (i.e. slidenotify) to refresh different subparts based on the event. Generally speaking, the parts and elements in the slide should not carry a reference to the slide as an initval. Instead the communications should be either through standard 'framexxx' or custom defined slide_xx defined by doTransition method.
    • Frames by design remove UI dependencies between different slides which makes synchronization of UI elements a non issue. However, for slides, the UI elements may need to be syncrhonized (i.e a grid view where a selection change on the grid will have to update the context menu). It is recommended that the slide define a transition called slide_notify which will then based on the notification will refresh the correct components.
    • Generally speaking, the parts and elements in the slide should not carry a reference to the slide as an initval. Instead the communications should be either through standard 'framexxx' or custom defined slidexx defined by doTransition method.

    Frames

    • Hold the state mapping from uri to the frame
    • Handle loading and destroying slides when nav changes occur and UI transitions between states
    • All the frame_xxx transitions will get routed to the frame.
    • The register themselves with the system using 'frame_register'
    • They intercept frame_notify transitions and bubble that app the sourcepart level via 'push'

    Embeddable Parts

    • Can be embedded via parts: 'ext'
    • Useful for implementing referencable controls: frames, collections, textbox, etc.
    • If you find yourself building deep hierarchies inside embedded parts for referencable components, it is a sign that that there is a componentization issue and the part needs to be broken down into pieces and the pieces pulled together using either a slide or splitter.
    • Communicate of states would be done via push.sourcepart.extpart:

    onnotify: [

    function(push) {

    modtask.action = push.sourcepart.extpart.keys.action || {};

    ....

    Instead of 'frame_xxx' just do

    tap: function(push) { push(push.sourcepart.extpart.seqs.internalSeqs); }

    Design Guidelines

    • Do not use splitters for referencable parts.
    • Splitters are used heavily for clonable components. They make seperation of states possible and allow for source code customization.
    • Referencable parts should not have deep hierarchies. If they do, that is generally a sign that they need to be broken down into pieces.

    Should a splitter be added into the user flow?

    Example 1: Wizard Flow
    Consider a sample update element wizard flow:

    View -> Edit -> Confirm -> Process -> Done -> (back) View

    We can capture the flow by defining navItems:

    [

    { path: 'view', views: { body: 'viewmod' } },

    { path: 'edit', views: { body: 'editmod' } }

    ]

    What this is doing:

    • capture the relevant UI for each step of the follow in a seperate slide module
    • A common mechanism for sharing states across these: each step works with a common data set (object being edited) which can be shared using the 'frameset/getkey'
    • The user can be guided between different stages by 'frame_navigate'
    • each slide can be maintained independent of others using the IDE.
    • The 'address' of each UI state is virtualized (/view, /edit, etc.), which means that the components have become context agnostic and dont care where in the visual hierarchy they might be. So inside each slide we can to frame_navigate and reference the sibling slides.
    • The browser address bar path is parsed and projected into each slide. This will make building landing pages, etc. a lot easier.
    • The slides are not tied to any route based state object; state management is done by landing on the view. This simplifies creating and maintaining slides.

    Contrast this with:

    [

    { path: 'wizardstep/*',

    views: { body: 'wizardmod' }

    pattern: {

    // will come out as itemid property in ['framegetkey', '_matches', modtask]

    matches: ['step']

    }

    }

    ]

    This approach will also give us the parsing of state from the uri to the matches.step variable. But now consider that inside the wizardmod we need to ext load a module based on the step key (to allow for implementation of each step into a seperate file so that it can be worked on seperately using the IDE) which would make the wizardmodule redundant.

    So in the case above mapping the states along navPaths in advantagous to mapping using matches.

    matches are useful when:

    • Need to capture user input, db ids, etc. in the UI
    Example 2: Browse Interface

    Consider the collection/view/list component. There is a design choice between implementing it as a frame which can then handle seletion info as a matches parameter.

    [{

    'path': 'collection/.*',

    pattern: {

    // will come out as itemid property in ['framegetkey', '_matches', modtask]

    matches: ['selectioncsv']

    },

    views: {

    body: 'item'

    }

    }]

    And the list of objects to be displayed can be passed in by framesetkey. Notice that this will mean that all the framexx interactions by the item will be trapped inside the collection frame and framenotify will need to be used by the item. In other words, one flaw of this approach is that the item will need to be aware of the collection frame and we need extra logic at the collection frame level to intercept and pass framenotify call to the layer above.

    The other problem that this will present is that defining side by side collections could become tricky as they splitter will by design will force a state change on one to affect the other.

    Now if we just implemented the collection/view/list component as a regular component that accepted the selection and objects as initval params, we wont have the problem mentioned above.

    Also notice that the first approach 'insulates' selection changes from affecting the layer above it because we are saying that the selection changes are restricted to the collection components. But if capture the selection state in the layer above, a change in selection will trigger a full redraw on the layer above which may not be desirable.

    To solve the insulation problem, we can always create a new path using the frame/minimal component to capture the state at that level.


  • Izyware Blog
    Izyware Blog