New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FLUID-6112: add a Developer Introduction to core concepts of Infusion #114
Conversation
|
||
IoC references allow us to refer to other parts of a component object (or another component entirely) in a declarative, context-specific manner, with `{that}` standing in for the current component configuration. | ||
|
||
We can use a listener definition, the `onCreate` lifecycle event and IoC `{that]` to have a component say hello when it's ready, rather than needing to be manually called: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo on this line '{that]'
As the display of mixed HTML/markdown paragraphs is broken on GitHub, I am reviewing in docpad. My first question is, where will this live? It's not linked into any of the top level categories at the moment. |
I'm getting the idea that this is meant to be a tutorial? It should be linked there. In any case, IMO it would be better to break this down into separate pages with a shared table of contents. For example, I think there's too big a gap between the first principles introduced and the summary. If you were to restructure into smaller pages, each page would hold part of the summary, and you could shorten each point in the overall summary and link to the section that demonstrates the principle. If you break it out into sections, you also have more room to link to background information on general concepts we are applying (I will comment inline with examples). |
|
||
The introduction assumes you are familiar with the basics of [JavaScript](https://developer.mozilla.org/en-US/docs/Learn/JavaScript) development, and with using a browser's [developer tools](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools). You should also have some experience of the [jQuery](https://jquery.com/) JavaScript library that Infusion is built on top of. | ||
|
||
We will present an increasingly complicated "Hello, World!" implementation to demonstrate the core concepts, with live examples throughout using the [CodePen](http://codepen.io/) service. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"complex" seems better than "complicated" here.
|
||
### Summing Up | ||
|
||
This elaborate "Hello, World!" implementation has slowly introduced some of Infusion's core features. To summarize: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps "moderately complex" instead of "elaborate" would be better here. Also, "introduces" rather than "has slowly introduced" seems better.
|
||
This elaborate "Hello, World!" implementation has slowly introduced some of Infusion's core features. To summarize: | ||
|
||
* We implement our programs by designing [components](#components) that work together to provide the needed functionality. Components are Javascript objects adhering to certain syntax conventions that are created using the `fluid.defaults` function. While components have defaults, any of these defaults can be overriden at the time a specific instance of the component is created. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned in my global comment, if you break things down by sections, you can expand on each concept within the section, and then use a condensed version here, linked to the expanded definition.
|
||
A new Infusion component is defined using the `fluid.default` function and a very basic "Hello, World!" component might look like this: | ||
|
||
<div class="infusion-docs-note">You can check out the [Live Example](http://codepen.io/waharnum/pen/oBYvwx?editors=1111) of the code below on [CodePen](http://codepen.io/)</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the codepen examples worked for me when I tested, seems to be a problem on their end.
}); | ||
``` | ||
|
||
Then, from the console, we'll use the ChangeApplier to change the model; notice how the modelListener we defined responds to the change and updates the message again: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Highlight ChangeApplier
in backticks.
``` | ||
|
||
Right now this component doesn't do anything new, but we will evolve its definition throughout this introduction to demonstrate further core concepts of the framework. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an example, this would be a natural point for a section/page break.
|
||
### Models and Model Components | ||
|
||
Mutable data is expected to be stored on a component's [model](/infusion/development/FrameworkConcepts.md#model-objects). Component models in Infusion are altered through the [ChangeApplier](/infusion/development/ChangeApplier.md) functionality, which works to: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be fleshed out more. We obviously use non-model mutable data (member variables) all the time. Also, assume they might not have familiarity with MVC or what's good to put in a model, a link and a sentence summary would be helpful.
``` | ||
var helloWorld = fluid.helloWorld({}); | ||
helloWorld.sayHello(); | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the risk of making this too complex, IMO it would be good to demonstrate how an invoker can be overridden.
|
||
### Restructuring Infusion Components | ||
|
||
Infusion's configuration-oriented components make it easier to restructure code, especially as component configuration becomes unwieldy. In the example below, we extract the two "say hello" components into separate component definitions from the main component, then include them as subcomponents of the main component. We've also added a listener to the main component to announce (once) when it is finished creation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"it is finished creation" seems odd. Perhaps "its creation is complete"?
}); | ||
``` | ||
|
||
### Using Invokers for Polymorphic Behaviour and Refactoring to Reuse Configuration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're going to use the word "polymorphic" multiple times in the doc, you should really have more than a deep dive link into our docs on the subject. A sentence summary of what we mean and a link to a WikiPedia article on the topic would be nice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or perhaps just add another link to "our" coverage of the subject here, you have one near the other references.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In thinking about this and reading the Wikipedia article, I removed all mentions of it in favour of simply talking about invoker/function overriding.
// except for its implementation in the invoker | ||
gradeNames: ["fluid.helloWorld.sayHello"], | ||
invokers: { | ||
sayHello: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I commented earlier about demonstrating overriding. Mentioning it at the end of the "invokers" section and linking to this section would be a good way to handle that.
* Components can include [subcomponents](#subcomponents-and-model-relaying), and use [model relaying](#subcomponents-and-model-relaying) to keep state synchronized between different components in larger designs. Many kinds of model relays are possible aside from two-way synchronization. | ||
* As program designs evolve, Infusion's configuration-oriented components make it easier to [restructure a design](#restructuring-infusion-components) by splitting out functionality into multiple components and wiring them together through IoC references. | ||
* When it becomes clear two components have similar behaviour, Infusion's design helps in [refactoring to share functionality](##using-invokers-for-polymorphic-behaviour-and-refactoring-to-reuse-configuration) through the use of invokers and base grades. | ||
* Infusion has strong supports for [multimodal implementations](#adding-further-ways-of-saying-hello) that allow programs to adapt themselves to new contexts for input and presentation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The summary needs a bit of work. As I've stated elsewhere, by this point you should be summarizing in much less detail, and linking back to the topic if people want to refresh their memory.
You should also really end with a "next steps" section, give them an idea of what they might do to continue learning from this point. Even something as simple as encouraging them to join the community and linking to those docs would be a good start.
I'm also noticing that we don't really make it easy to close the loop. We should end most tutorials with some idea of how to give feedback. If we say it only in introductory material, people are likely to forget it if they have questions or find errors while reading the actual tutorial.
@the-t-in-rtf, thanks for all the comments - I think splitting it out into separate pages is entirely appropriate. I'd begun writing this as a short one-pager, and then it sort of evolved as I decided it needed to have code examples to illustrate the comments. I'll be working on revisions in the next day or so once others have had a chance to comment. |
|
||
# Introduction | ||
|
||
Here we will boil down some of the basic concepts of Infusion for developers who may be interested in it, but uncertain of where to start. There's a lot going on in the framework, but grasping some core ideas helps a great deal in moving forward and learning. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really great work on this tutorial, WWAHHARNNUM!
After definition, instances of the component can be created by calling the component's name as a function, with the option to pass in further configuration options as an argument: | ||
|
||
``` | ||
var helloWorld = fluid.helloWorld({}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can leave out the {} since there are no options
|
||
Programs using Infusion structure their data, functionality and interaction as various components defined using a common syntax. | ||
|
||
Components are [regular JavaScript objects that have certain characteristics](/infusion/development/UnderstandingInfusionComponents.md). Components can be freely combined together to form new components using the [grades system](/infusion/development/ComponentGrades.md), or organized into relationships with one another via [subcomponents](/infusion/development/SubcomponentDeclaration.md). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what it really adds to say that they are "regular JavaScript objects", but I guess it's the kind of thing that people say. You might want to say something, even at this early stage, about how they have their lifetime and scoping managed by the framework. Whilst you could say they are "a bit regular" they are not, for example, plain JSON-equivalent objects since (at least for the last couple of years) they have a non-default prototype supplied via Object.create().
|
||
Component-based development emphasizes declarative configuration, loose coupling and flexible hierarchies. | ||
|
||
A new Infusion component is defined using the `fluid.default` function and a very basic "Hello, World!" component might look like this: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo, should be fluid.defaults
}); | ||
``` | ||
|
||
### Restructuring Infusion Components |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good example - since my first thought on reading the previous section was, "These definitions should be extracted as grades" : P
We'll summarize what we've done below, then suggest some next steps. | ||
|
||
<div class="infusion-docs-note"><strong>Note:</strong> If you have feedback about this tutorial, we'd be glad to hear it via our <a href="https://wiki.fluidproject.org/display/fluid/IRC+Channel">IRC channels</a>, <a href="https://wiki.fluidproject.org/display/fluid/Mailing+Lists">mailing lists</a> or a <a href="https://github.com/fluid-project/infusion-docs/issues">GitHub issue on the documentation repo</a></div> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we'd prefer to have them file issues in JIRA instead. It is something to think about if we want to use the separate github issue tracker, but we have been keeping most things in JIRA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I vaguely recall I had some rationale based on a conversation with someone about asking to file documentation issues in the GitHub tracker, but I cannot for the life of me remember the details, or if this conversation actually occurred. I'll update it to point to the JIRA tracker instead.
|
||
## Summing Up | ||
|
||
* We implement our programs by designing [components](DeveloperIntroductionToInfusionFramework-Components.html) that work together to provide the needed functionality. Components are Javascript objects adhering to certain syntax conventions that are created using the `fluid.defaults` function. While components have defaults, any of these defaults can be overriden at the time a specific instance of the component is created. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
References to other documentation pages should all point at the MD version, same throughout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching this issue - they should all be fixed now.
@jobara regarding the redirect, on the docs platform we have one link currently in I'd feel fine about eliminating the redirect and changing the link from |
@waharnum okay, lets remove the redirect for now. If it becomes an issue we can think of ways to address it. Regarding the link in the SetUpYourEnvironment.md, what is the difference between the getting started tutorial and the developer introduction? Does the latter expand on the former? |
@jobara I've removed the redirect and (per our conversation) the link from the "Getting Started" tutorial. |
@jobara missed that one, sorry - fixed now. |
* We implement our programs by designing [components](DeveloperIntroductionToInfusionFramework-Components.md) that work together to provide the needed functionality. Components are Javascript objects adhering to certain syntax conventions that are created using the `fluid.defaults` function. While components have defaults, any of these defaults can be overriden at the time a specific instance of the component is created. | ||
* Components use [invokers](DeveloperIntroductionToInfusionFramework-Invokers.md) to expose functionality "publicly", provide a consistent API for collaboration with other components or use by other code, and enable function overriding when deriving new components from existing ones. | ||
* All components support [events and inversion of control](DeveloperIntroductionToInfusionFramework-EventsAndInversionOfControl.md); these allow our programs to be built up of loosely coupled parts, and to manage sequencing through components observing and responding to their own events or the events of other components. | ||
* Components that need to track mutable data, state or content should be [model components](DeveloperIntroductionToInfusionFramework-ModelsAndModelComponents.md); model components can coordinate and synchronize their data with other model components, fire events when their models are changed, and take other actions to store and respond to state changes. Model components can use [model listeners](DeveloperIntroductionToInfusionFramework-ListeningToModelChanges.md) to respond to changes in model state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "model listeners" link is broken.
|
||
* Get [your own copy of Infusion from our GitHub repository](https://github.com/fluid-project/infusion). | ||
* Read about the [framework concepts](/FrameworkConcepts.md) to learn more about Infusion's design goals and overall philosophy. | ||
* Read [further documentation on Infusion](/), including many advanced topics not covered here such as [using Infusion in node.js](/NodeAPI.md), [advanced features of model transformation](/ModelTransformationAPI.md) and [unit testing](/jqUnit.md). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the relative links in the "Where to Go Next?" section are broken. Probably because they are relative to the infusion docs and not the tutorials.
|
||
Here we will boil down some of the basic concepts of Infusion for developers who may be interested in it, but uncertain of where to start. There's a lot going on in the framework, but grasping some core ideas helps a great deal in moving forward and learning. | ||
|
||
This introduction summarizes some topics (and leaves out many others) that are gone into at length in the [full framework documentation](/), and is focused on developers trying to orient themselves to the framework for the first time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Full framework documentation" link is broken
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May only be broken in the github view.
|
||
3. [Events and Inversion of Control](DeveloperIntroductionToInfusionFramework-EventsAndInversionOfControl.md) to allow our programs to be built out of loosely coupled parts, and to manage sequencing and lifecycle throughout that loosely coupled structure. | ||
|
||
4. [Model Components](DeveloperIntroductionToInfusionFramework-ModelsAndModelComponents.md) that can track mutable data, state or content, and coordinate and synchronize their data with other model components and fire events when their state changes. [Model Listeners](DeveloperIntroductionToInfusionFramework-ListeningToModelChanges.md) are used to respond to changes in model state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Model Listeners" link is broken
@jobara I've fixed the link issues you've noted. Regarding the "Getting Started With Infusion" (http://docs.fluidproject.org/infusion/development/tutorial-gettingStartedWithInfusion/GettingStartedWithInfusion.html) tutorial and this one, I've got the following observations:
What I'd propose for now is renaming "Getting Started" to something like "Getting Started with Infusion Component Design" - a lot of the material is about component design choices and figuring out which are appropriate (very valuable material, in more detail than what's in the new tutorial). We can keep the file names the same to avoid losing links from other places and the relationship between the tutorials is more clear. Longer term (after the new Renderer, perhaps), I think we should rewrite the tutorial to be a more advanced coverage of building Infusion-based applications. How does that sound? |
@waharnum that seems reasonable to me. |
@jobara I've renamed the Getting Started tutorial accordingly and made a few changes to the wording of the opening to make it clearer by comparison to the Developer Introduction - have a look and let me know your thoughts? |
You'll notice that in this case we have been able to avoid binding to the entire component instance in our public function, and so our standalone public function `tutorials.currencyConverterAuto.convert` | ||
is of more general utility than just for building a component method. | ||
You'll notice that in this case we have been able to avoid binding to the entire component instance in our public function, and so our standalone public function `tutorials.currencyConverterAuto.convert` | ||
is of more general utility than just for building a component method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you fix the bug in the code example code that this refers to. The function takes in exchangeRate
but then uses that.options.exchangeRate
internally.
@michelled did you finish looking over the content of this PR, is it okay to go in from the stand point. I think I've finished reviewing the structural/syntax parts now. |
Yep, I'm happy with it! |
Merged at aa4b061 |
JIRA: https://issues.fluidproject.org/browse/FLUID-6112
This is a document for Infusion 2.0 in the style of https://wiki.fluidproject.org/display/docs/Developer+Introduction+to+Infusion+Framework; it stays away from the pre-built components entirely (those might be covered in another, similar document) in favour of explaining some of the most important core framework concepts. It assumes a developer has some experience with Javascript development and jQuery.
I've used CodePen at each stage for a live code example of what's being demonstrated.
Tear it up, because we want this to be useful for people who haven't worked with the framework before. :)