SlideShare una empresa de Scribd logo
1 de 78
Descargar para leer sin conexión
SOSUiComponents
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Alternative titles:
Lessons learned from UiComponents
or
My own best practices for UiComponents
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
I'm assuming you have at least a (very)
basic understanding of
— require.js
— Knockout.js
— jQuery UI Widgets
— UiComponents
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
UiComponents
So what is the problem?
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
For me grokking UiComponents was one
of the hardest things
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
It still takes me a long time to do some
things that I expect to be quick
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
I try to understand UiComponents mainly
by reading code
Reading Code > Reading Docs
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
So I try to optimize code for reading
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
This talk
1. A little bit of whining
2. General advice on readable code
3. View state management
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Three issues I frequently encounter:
1. High cognitive load
2. Duplication of knowledge
3. State is coupled to the DOM
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
If it was my job...
..to fix UiComponents
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Cognitive load
Super verbose declaration
(no sane defaults)
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Cognitive load
Mixing of concepts
(Knockout.js and jQuery UI Widgets)
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Cognitive load
Inconsistent use in core
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Self
Documenting
CodeSOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Rules I try to apply to code I write.
When working with the core code...
well, it is what it is.
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
4 Rules of simple design by Kent Beck:
1. Passes all tests
2. Reveals intent
3. No duplication
4. Fewest elements
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Passes all tests
The code has to work.
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
Good naming
— Descriptive base class names
— Intent of functions, not
implementation
— Descriptive properties and variables
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
bad:
interface ButtonProviderInterface
{
/**
* Retrieve button-specified settings
*
* @return array
*/
public function getButtonData();
}
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
because:
public function getButtonData()
{
// ...
return [
'label' => __('Save'),
'class' => 'save primary',
'data_attribute' => [
'mage-init' => [
'buttonAdapter' => [
'actions' => [
[
'targetName' => 'product_form.product_form',
'actionName' => 'save',
'params' => [false]
]
]
]
]
],
'class_name' => Container::SPLIT_BUTTON,
'options' => $this->getOptions(),
];
}
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
better:
interface ButtonProviderInterface
{
public function getLabel();
public function getCssClassNames();
public function getActions();
...
}
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
bad:
{
getSortOrder: function () {
return this.order;
}
}
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
good:
{
isDescending: function() {
return this.order === SORT_DESC;
},
isAscending: function() {
return this.order === SORT_ASC;
}
}
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
Try to use a style familiar to
the most likely reader
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
Favor UiComponent JSON over XML
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
<item name="progressBar" xsi:type="array">
<item name="sortOrder" xsi:type="string">0</item>
<item name="component" xsi:type="string">Magento_Checkout/js/view/progress-bar</item>
<item name="displayArea" xsi:type="string">progressBar</item>
<item name="config" xsi:type="array">
<item name="deps" xsi:type="array">
<item name="0" xsi:type="string">checkout.steps.shipping-step.shippingAddress</item>
<item name="1" xsi:type="string">checkout.steps.billing-step.payment</item>
</item>
</item>
</item>
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Reveals intent
{
"progressBar": {
"component": "Magento_Checkout/js/view/progress-bar",
"sortOrder": 0,
"displayArea": "progressBar",
"config": {
"deps": [
"checkout.steps.shipping-step.shippingAddress",
"checkout.steps.billing-step.payment"
]
}
}
}
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
Keep knowledge in one place
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
Duplication is a common problem in M2
EAV, DataInterfaces, UiComponents,
GraphQL, ...
How does it apply in the view layer?
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
Avoid selectors in view models
loginFormSelector = 'form[data-role=email-with-possible-login]',
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
:'-(
miniCart.sidebar({
'targetElement': 'div.block.block-minicart',
'button': {
'checkout': '#top-cart-btn-checkout',
'remove': '#mini-cart a.action.delete',
'close': '#btn-minicart-close'
},
'showcart': {
'parent': 'span.counter',
'qty': 'span.counter-number',
'label': 'span.counter-label'
},
'minicart': {
'list': '#mini-cart',
'content': '#minicart-content-wrapper',
'qty': 'div.items-total',
'subtotal': 'div.subtotal span.price'
},
'item': {
'qty': ':input.cart-item-qty',
'button': ':button.update-cart-item'
}
});
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
If selectors are required?
Keep the definition and the configuration
as close as possible,
ideally in the same file
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
DOM selector declaration and config
<div data-bind="scope: 'foo'">
<div data-role="message-container">...</div>
</div>
<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"foo": {
"component": "MyCompany_MyModule/js/view/foo",
"containerSelector": "div[data-role=message-container]"
}
}
}
}
}
</script>
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
UiComponent selector declaration and config
<div data-bind="scope: 'messages'">
...
</div>
<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"messages": {
"component": "Magento_Theme/js/view/messages"
}
}
}
}
}
</script>
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
Keep knowledge in one file and close together.
<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"appRoot": {
"component": "My_Module/js/root"
"children": {
"thingA": {
"component: "My_Module/js/thing-a"
},
"thingB": {
"component: "My_Module/js/thing-b",
"sibling":" "thingA"
}
}
}
}
}
}
}
</script>
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
Injecting DOM-Nodes is better
E.g. with a custom binding:
<div data-bind="scope: 'myViewModel', bindDomNode: true">
</div>
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
Custom binding handler declaration:
define(['ko'], function(ko) {
'use strict';
ko.bindingHandlers.bindDomNode = {
init: function(element, valueAccessor, _a, _b, bindingContext) {
if (valueAccessor()) {
bindingContext.$data.domNode = element;
}
}
};
});
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
No duplication
Example access of injected DOM node the view model:
this.domNode.getBoundingClientRect();
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Fewest elements
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Fewest elements
If something works,
expresses intent
and contains no duplicate knowledge,
don't split it further
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Fewest elements
The Single Responsibility Principle is not
the Single Public Method Principle.
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Fewest elements
If things are related, keep them together.
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Managing
State
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Context: Magento <= 2.2.2
Not a SPA/PWA
SRP with several frontend "components",
each with its own more or less
independent state.
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
We have three options.
1. Keep state in the DOM or
UiComponents
2. Pass state from root down to children
3. Keep state outside of the view
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Example TicTacToe
https://github.com/Vinai/example-module-tictactoe
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Example TicTacToe
Shamelessly stolen from https://reactjs.org/tutorial/tutorial.html
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Example TicTacToe
Simple example for each approach to
managing shared state:
https://github.com/Vinai/example-module-tictactoe
$ git branch
* 0-in-component-state
1-pass-to-children
2-external-state
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
1. Keep state in the DOM or
UiComponents
E.g. jQuery or pure Knockout.js
Only for simplest, single component cases
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
1. State in the DOM
How is state stored in the DOM?
— Form element values
— CSS classes (e.g. "active" or "invalid")
— Inline styles (e.g. "display: none")
— Element attributes (e.g. disabled)
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
1. State in the DOM
DOM state storage is common with jQuery
self.element.off('submit');
// disable 'Add to Cart' button
addToCartButton = $(form).find(this.options.addToCartButtonSelector);
addToCartButton.prop('disabled', true);
addToCartButton.addClass(this.options.addToCartButtonDisabledClass);
form.submit();
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
1. State in UiComponents
Properties on the knockout view model
Shared state: imports, exports, links
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
1. State in UiComponents
Component.extend({
defaults: {
links: {
squares: '${ $.provider }:squares'
},
imports: {
xIsNext: '${ $.provider }:xIsNext',
winner: '${ $.provider }:winner'
}
},
square: function () {
return this.squares[this.squareIndex];
}
handleClick: function () {
const square = this.square();
if ('' === square() && !this.winner) {
square(this.xIsNext ? 'X' : 'O');
}
}
});
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
1. Shared state in DOM or UiComponents
Strong coupling through
cross-component dependencies
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
1. Derived state
In this approach state derived from one
model is o!en stored in another model
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
1. Derived State
updateFoo: function() {
this.foo = this.other.bar * this.other.bar;
}
// vs.
foo: function() {
return this.other.bar * this.other.bar;
}
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
2. Pass state from root down to children
E.g. pure react components
Works within one component hierarchy
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
2. Example from React TicTacToe
<Board
squares={current.squares}
onClick={i => this.handleClick(i)}
/>
class Board extends React.Component {
renderSquare(i) {
return (
<Square
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
/>
);
}
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
2. Pass state from root down to children
Problem when state is required outside
one hierarchy
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
2. Pass state from root down to children
Not common in Magento 2
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
2. Pass state from root down to children
No callback on parent, only on child
Component.extend({
initContainer: function (parent) {
const state = parent.state;
this.cells = [...state.squares.keys()].map(function (i) {
return new Square({index: i, state: state});
});
return this._super(parent);
}
...
}
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
3. Keep state outside the view
E.g. Elm architecture, flux, redux/vuex
Most versatile but needs more plumbing
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
3. Keep state outside the view
There are differences:
Naming, (im)mutability, 1 or 2 way data
flow, (F)RP, effects handling, amount of
architecture...
But there always is a single state storage
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
3. Separate state with UiComponents
State object with observable properties
define(['ko'], function (ko) {
'use strict';
return ko.track({
moves: [],
squares: [...Array(9).keys()].map(() => ko.observable('')),
xIsNext: true,
winner: false
});
});
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
3. Separate state with UiComponents
Require and use state container object
define(
['uiComponent', 'ticTacToeState'],
function (Component, state) {
'use strict';
return Component.extend({
...
handleClick: function () {
if ('' === this.value() && !state.winner) {
state.squares[this.index](state.xIsNext ? 'X' : 'O');
}
},
});
}
);
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Example Breakout
https://github.com/Vinai/example-module-breakout
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
3. Multiple state storage objects
define(
['gameComponent', 'ballState', 'frameState', 'gameState'],
function (GameComponent, ball, frame, game) {
'use strict';
return GameComponent.extend({
initialize: function () {
this._super();
this.initDimensions(frame);
frame.width = function () {
return game.width * .98;
};
frame.height = function () {
return game.height * .80;
};
frame.left = function () {
return game.width * .01;
};
frame.top = function () {
return game.height * .19;
};
},
...
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
3. State outside the view
Benefits:
— State is simple to share
— View models contain mostly only logic
— Less code
— Easier to understand
— More maintainable
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Recommendations
for maintainable UiComponents...
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
The code needs to...
1. Pass all tests
2. Reveal intent
3. Contain no duplication
4. Have the fewest possible elements
5. Separate shared state from the view
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
Thanks to Kent Beck for his timeless
4 rules of simple design.
Thank you for your attention!
SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018

Más contenido relacionado

Similar a SOS UiComponents

Magento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata IntroMagento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata Introvinaikopp
 
Funnel Analysis with Apache Spark and Druid
Funnel Analysis with Apache Spark and DruidFunnel Analysis with Apache Spark and Druid
Funnel Analysis with Apache Spark and DruidDatabricks
 
Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018vinaikopp
 
Strategies for the seamless deployment of travel diary collection systems to ...
Strategies for the seamless deployment of travel diary collection systems to ...Strategies for the seamless deployment of travel diary collection systems to ...
Strategies for the seamless deployment of travel diary collection systems to ...Adrian C. Prelipcean
 
Let's understand Data Science
Let's understand Data Science Let's understand Data Science
Let's understand Data Science Sachin Rastogi
 
Preserving a Web of Linked Data: Lessons and challenges from a fading web
Preserving a Web of Linked Data: Lessons and challenges from a fading webPreserving a Web of Linked Data: Lessons and challenges from a fading web
Preserving a Web of Linked Data: Lessons and challenges from a fading webMiel Vander Sande
 
Developing web applications in 2010
Developing web applications in 2010Developing web applications in 2010
Developing web applications in 2010Ignacio Coloma
 
Digital cultural heritage spring 2015 day 3
Digital cultural heritage spring 2015 day 3Digital cultural heritage spring 2015 day 3
Digital cultural heritage spring 2015 day 3Stefano A Gazziano
 
Debugging - things your senior hasn't told you about
Debugging - things your senior hasn't told you aboutDebugging - things your senior hasn't told you about
Debugging - things your senior hasn't told you aboutCarola Nitz
 
Contribution day guide. MM19ES 2019
Contribution day guide. MM19ES 2019Contribution day guide. MM19ES 2019
Contribution day guide. MM19ES 2019Oleksii Korshenko
 
App Indexing & Mobile SEO - Friends of Search 2016
App Indexing & Mobile SEO - Friends of Search 2016App Indexing & Mobile SEO - Friends of Search 2016
App Indexing & Mobile SEO - Friends of Search 2016MobileMoxie
 
Architecture in-the-small-slides
Architecture in-the-small-slidesArchitecture in-the-small-slides
Architecture in-the-small-slidesvinaikopp
 
Geek Moot '09 -- Multilang Implemenatation
Geek Moot '09 -- Multilang ImplemenatationGeek Moot '09 -- Multilang Implemenatation
Geek Moot '09 -- Multilang ImplemenatationTed Kulp
 
Optimizing Spark-based data pipelines - are you up for it?
Optimizing Spark-based data pipelines - are you up for it?Optimizing Spark-based data pipelines - are you up for it?
Optimizing Spark-based data pipelines - are you up for it?Itai Yaffe
 
Get Into Open Source
Get Into Open SourceGet Into Open Source
Get Into Open SourceJoe Sepi
 
Single page applications & SharePoint
Single page applications & SharePointSingle page applications & SharePoint
Single page applications & SharePointFabio Franzini
 
INRA @ Scilab Conference 2018
INRA @ Scilab Conference 2018INRA @ Scilab Conference 2018
INRA @ Scilab Conference 2018Scilab
 
Writing Testable Code (for Magento 1 and 2) 2016 Romaina
Writing Testable Code (for Magento 1 and 2)  2016 RomainaWriting Testable Code (for Magento 1 and 2)  2016 Romaina
Writing Testable Code (for Magento 1 and 2) 2016 Romainavinaikopp
 
UXDX Berlin - Test & Deploy, by Quentin Berder, President, WiredCraft
UXDX Berlin - Test & Deploy, by Quentin Berder, President, WiredCraftUXDX Berlin - Test & Deploy, by Quentin Berder, President, WiredCraft
UXDX Berlin - Test & Deploy, by Quentin Berder, President, WiredCraftUXDXConf
 

Similar a SOS UiComponents (20)

Magento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata IntroMagento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata Intro
 
Funnel Analysis with Apache Spark and Druid
Funnel Analysis with Apache Spark and DruidFunnel Analysis with Apache Spark and Druid
Funnel Analysis with Apache Spark and Druid
 
Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018
 
Strategies for the seamless deployment of travel diary collection systems to ...
Strategies for the seamless deployment of travel diary collection systems to ...Strategies for the seamless deployment of travel diary collection systems to ...
Strategies for the seamless deployment of travel diary collection systems to ...
 
Let's understand Data Science
Let's understand Data Science Let's understand Data Science
Let's understand Data Science
 
Preserving a Web of Linked Data: Lessons and challenges from a fading web
Preserving a Web of Linked Data: Lessons and challenges from a fading webPreserving a Web of Linked Data: Lessons and challenges from a fading web
Preserving a Web of Linked Data: Lessons and challenges from a fading web
 
Developing web applications in 2010
Developing web applications in 2010Developing web applications in 2010
Developing web applications in 2010
 
Digital cultural heritage spring 2015 day 3
Digital cultural heritage spring 2015 day 3Digital cultural heritage spring 2015 day 3
Digital cultural heritage spring 2015 day 3
 
Debugging - things your senior hasn't told you about
Debugging - things your senior hasn't told you aboutDebugging - things your senior hasn't told you about
Debugging - things your senior hasn't told you about
 
Contribution day guide. MM19ES 2019
Contribution day guide. MM19ES 2019Contribution day guide. MM19ES 2019
Contribution day guide. MM19ES 2019
 
Real_World_0days.pdf
Real_World_0days.pdfReal_World_0days.pdf
Real_World_0days.pdf
 
App Indexing & Mobile SEO - Friends of Search 2016
App Indexing & Mobile SEO - Friends of Search 2016App Indexing & Mobile SEO - Friends of Search 2016
App Indexing & Mobile SEO - Friends of Search 2016
 
Architecture in-the-small-slides
Architecture in-the-small-slidesArchitecture in-the-small-slides
Architecture in-the-small-slides
 
Geek Moot '09 -- Multilang Implemenatation
Geek Moot '09 -- Multilang ImplemenatationGeek Moot '09 -- Multilang Implemenatation
Geek Moot '09 -- Multilang Implemenatation
 
Optimizing Spark-based data pipelines - are you up for it?
Optimizing Spark-based data pipelines - are you up for it?Optimizing Spark-based data pipelines - are you up for it?
Optimizing Spark-based data pipelines - are you up for it?
 
Get Into Open Source
Get Into Open SourceGet Into Open Source
Get Into Open Source
 
Single page applications & SharePoint
Single page applications & SharePointSingle page applications & SharePoint
Single page applications & SharePoint
 
INRA @ Scilab Conference 2018
INRA @ Scilab Conference 2018INRA @ Scilab Conference 2018
INRA @ Scilab Conference 2018
 
Writing Testable Code (for Magento 1 and 2) 2016 Romaina
Writing Testable Code (for Magento 1 and 2)  2016 RomainaWriting Testable Code (for Magento 1 and 2)  2016 Romaina
Writing Testable Code (for Magento 1 and 2) 2016 Romaina
 
UXDX Berlin - Test & Deploy, by Quentin Berder, President, WiredCraft
UXDX Berlin - Test & Deploy, by Quentin Berder, President, WiredCraftUXDX Berlin - Test & Deploy, by Quentin Berder, President, WiredCraft
UXDX Berlin - Test & Deploy, by Quentin Berder, President, WiredCraft
 

Más de vinaikopp

Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023vinaikopp
 
Hyvä: Compatibility Modules
Hyvä: Compatibility ModulesHyvä: Compatibility Modules
Hyvä: Compatibility Modulesvinaikopp
 
Hyvä from a developer perspective
Hyvä from a developer perspectiveHyvä from a developer perspective
Hyvä from a developer perspectivevinaikopp
 
Property Based Testing in PHP
Property Based Testing in PHPProperty Based Testing in PHP
Property Based Testing in PHPvinaikopp
 
Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019vinaikopp
 
ClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRNClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRNvinaikopp
 
Magento 2 TDD Code Kata
Magento 2 TDD Code KataMagento 2 TDD Code Kata
Magento 2 TDD Code Katavinaikopp
 
Testing Magento 2
Testing Magento 2Testing Magento 2
Testing Magento 2vinaikopp
 
ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017vinaikopp
 
Lizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17deLizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17devinaikopp
 
Stories from the other side
Stories from the other sideStories from the other side
Stories from the other sidevinaikopp
 
Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)vinaikopp
 
Writing testable Code (MageTitans Mini 2016)
Writing testable Code (MageTitans Mini 2016)Writing testable Code (MageTitans Mini 2016)
Writing testable Code (MageTitans Mini 2016)vinaikopp
 
Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)vinaikopp
 
Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)vinaikopp
 
Modern Module Architecture
Modern Module ArchitectureModern Module Architecture
Modern Module Architecturevinaikopp
 
The beautiful Magento module - MageTitans 2014
The beautiful Magento module - MageTitans 2014The beautiful Magento module - MageTitans 2014
The beautiful Magento module - MageTitans 2014vinaikopp
 

Más de vinaikopp (17)

Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023
 
Hyvä: Compatibility Modules
Hyvä: Compatibility ModulesHyvä: Compatibility Modules
Hyvä: Compatibility Modules
 
Hyvä from a developer perspective
Hyvä from a developer perspectiveHyvä from a developer perspective
Hyvä from a developer perspective
 
Property Based Testing in PHP
Property Based Testing in PHPProperty Based Testing in PHP
Property Based Testing in PHP
 
Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019
 
ClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRNClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRN
 
Magento 2 TDD Code Kata
Magento 2 TDD Code KataMagento 2 TDD Code Kata
Magento 2 TDD Code Kata
 
Testing Magento 2
Testing Magento 2Testing Magento 2
Testing Magento 2
 
ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017
 
Lizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17deLizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17de
 
Stories from the other side
Stories from the other sideStories from the other side
Stories from the other side
 
Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)
 
Writing testable Code (MageTitans Mini 2016)
Writing testable Code (MageTitans Mini 2016)Writing testable Code (MageTitans Mini 2016)
Writing testable Code (MageTitans Mini 2016)
 
Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)
 
Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)
 
Modern Module Architecture
Modern Module ArchitectureModern Module Architecture
Modern Module Architecture
 
The beautiful Magento module - MageTitans 2014
The beautiful Magento module - MageTitans 2014The beautiful Magento module - MageTitans 2014
The beautiful Magento module - MageTitans 2014
 

Último

Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 

Último (20)

Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 

SOS UiComponents

  • 1. SOSUiComponents SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 2. SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 3. Alternative titles: Lessons learned from UiComponents or My own best practices for UiComponents SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 4. I'm assuming you have at least a (very) basic understanding of — require.js — Knockout.js — jQuery UI Widgets — UiComponents SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 5. SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 6. SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 7. SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 8. UiComponents So what is the problem? SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 9. For me grokking UiComponents was one of the hardest things SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 10. It still takes me a long time to do some things that I expect to be quick SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 11. I try to understand UiComponents mainly by reading code Reading Code > Reading Docs SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 12. So I try to optimize code for reading SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 13. This talk 1. A little bit of whining 2. General advice on readable code 3. View state management SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 14. Three issues I frequently encounter: 1. High cognitive load 2. Duplication of knowledge 3. State is coupled to the DOM SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 15. If it was my job... ..to fix UiComponents SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 16. Cognitive load Super verbose declaration (no sane defaults) SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 17. Cognitive load Mixing of concepts (Knockout.js and jQuery UI Widgets) SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 18. Cognitive load Inconsistent use in core SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 19. Self Documenting CodeSOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 20. Rules I try to apply to code I write. When working with the core code... well, it is what it is. SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 21. 4 Rules of simple design by Kent Beck: 1. Passes all tests 2. Reveals intent 3. No duplication 4. Fewest elements SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 22. Passes all tests The code has to work. SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 23. Reveals intent SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 24. Reveals intent Good naming — Descriptive base class names — Intent of functions, not implementation — Descriptive properties and variables SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 25. Reveals intent bad: interface ButtonProviderInterface { /** * Retrieve button-specified settings * * @return array */ public function getButtonData(); } SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 26. Reveals intent because: public function getButtonData() { // ... return [ 'label' => __('Save'), 'class' => 'save primary', 'data_attribute' => [ 'mage-init' => [ 'buttonAdapter' => [ 'actions' => [ [ 'targetName' => 'product_form.product_form', 'actionName' => 'save', 'params' => [false] ] ] ] ] ], 'class_name' => Container::SPLIT_BUTTON, 'options' => $this->getOptions(), ]; } SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 27. Reveals intent better: interface ButtonProviderInterface { public function getLabel(); public function getCssClassNames(); public function getActions(); ... } SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 28. Reveals intent bad: { getSortOrder: function () { return this.order; } } SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 29. Reveals intent good: { isDescending: function() { return this.order === SORT_DESC; }, isAscending: function() { return this.order === SORT_ASC; } } SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 30. Reveals intent Try to use a style familiar to the most likely reader SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 31. Reveals intent Favor UiComponent JSON over XML SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 32. Reveals intent <item name="progressBar" xsi:type="array"> <item name="sortOrder" xsi:type="string">0</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/progress-bar</item> <item name="displayArea" xsi:type="string">progressBar</item> <item name="config" xsi:type="array"> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.steps.shipping-step.shippingAddress</item> <item name="1" xsi:type="string">checkout.steps.billing-step.payment</item> </item> </item> </item> SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 33. Reveals intent { "progressBar": { "component": "Magento_Checkout/js/view/progress-bar", "sortOrder": 0, "displayArea": "progressBar", "config": { "deps": [ "checkout.steps.shipping-step.shippingAddress", "checkout.steps.billing-step.payment" ] } } } SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 34. No duplication SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 35. No duplication Keep knowledge in one place SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 36. No duplication Duplication is a common problem in M2 EAV, DataInterfaces, UiComponents, GraphQL, ... How does it apply in the view layer? SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 37. No duplication Avoid selectors in view models loginFormSelector = 'form[data-role=email-with-possible-login]', SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 38. No duplication :'-( miniCart.sidebar({ 'targetElement': 'div.block.block-minicart', 'button': { 'checkout': '#top-cart-btn-checkout', 'remove': '#mini-cart a.action.delete', 'close': '#btn-minicart-close' }, 'showcart': { 'parent': 'span.counter', 'qty': 'span.counter-number', 'label': 'span.counter-label' }, 'minicart': { 'list': '#mini-cart', 'content': '#minicart-content-wrapper', 'qty': 'div.items-total', 'subtotal': 'div.subtotal span.price' }, 'item': { 'qty': ':input.cart-item-qty', 'button': ':button.update-cart-item' } }); SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 39. No duplication If selectors are required? Keep the definition and the configuration as close as possible, ideally in the same file SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 40. No duplication DOM selector declaration and config <div data-bind="scope: 'foo'"> <div data-role="message-container">...</div> </div> <script type="text/x-magento-init"> { "*": { "Magento_Ui/js/core/app": { "components": { "foo": { "component": "MyCompany_MyModule/js/view/foo", "containerSelector": "div[data-role=message-container]" } } } } } </script> SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 41. No duplication UiComponent selector declaration and config <div data-bind="scope: 'messages'"> ... </div> <script type="text/x-magento-init"> { "*": { "Magento_Ui/js/core/app": { "components": { "messages": { "component": "Magento_Theme/js/view/messages" } } } } } </script> SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 42. No duplication Keep knowledge in one file and close together. <script type="text/x-magento-init"> { "*": { "Magento_Ui/js/core/app": { "components": { "appRoot": { "component": "My_Module/js/root" "children": { "thingA": { "component: "My_Module/js/thing-a" }, "thingB": { "component: "My_Module/js/thing-b", "sibling":" "thingA" } } } } } } } </script> SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 43. No duplication Injecting DOM-Nodes is better E.g. with a custom binding: <div data-bind="scope: 'myViewModel', bindDomNode: true"> </div> SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 44. No duplication Custom binding handler declaration: define(['ko'], function(ko) { 'use strict'; ko.bindingHandlers.bindDomNode = { init: function(element, valueAccessor, _a, _b, bindingContext) { if (valueAccessor()) { bindingContext.$data.domNode = element; } } }; }); SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 45. No duplication Example access of injected DOM node the view model: this.domNode.getBoundingClientRect(); SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 46. Fewest elements SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 47. Fewest elements If something works, expresses intent and contains no duplicate knowledge, don't split it further SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 48. Fewest elements The Single Responsibility Principle is not the Single Public Method Principle. SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 49. Fewest elements If things are related, keep them together. SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 50. Managing State SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 51. Context: Magento <= 2.2.2 Not a SPA/PWA SRP with several frontend "components", each with its own more or less independent state. SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 52. We have three options. 1. Keep state in the DOM or UiComponents 2. Pass state from root down to children 3. Keep state outside of the view SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 53. Example TicTacToe https://github.com/Vinai/example-module-tictactoe SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 54. Example TicTacToe Shamelessly stolen from https://reactjs.org/tutorial/tutorial.html SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 55. Example TicTacToe Simple example for each approach to managing shared state: https://github.com/Vinai/example-module-tictactoe $ git branch * 0-in-component-state 1-pass-to-children 2-external-state SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 56. 1. Keep state in the DOM or UiComponents E.g. jQuery or pure Knockout.js Only for simplest, single component cases SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 57. 1. State in the DOM How is state stored in the DOM? — Form element values — CSS classes (e.g. "active" or "invalid") — Inline styles (e.g. "display: none") — Element attributes (e.g. disabled) SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 58. 1. State in the DOM DOM state storage is common with jQuery self.element.off('submit'); // disable 'Add to Cart' button addToCartButton = $(form).find(this.options.addToCartButtonSelector); addToCartButton.prop('disabled', true); addToCartButton.addClass(this.options.addToCartButtonDisabledClass); form.submit(); SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 59. 1. State in UiComponents Properties on the knockout view model Shared state: imports, exports, links SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 60. 1. State in UiComponents Component.extend({ defaults: { links: { squares: '${ $.provider }:squares' }, imports: { xIsNext: '${ $.provider }:xIsNext', winner: '${ $.provider }:winner' } }, square: function () { return this.squares[this.squareIndex]; } handleClick: function () { const square = this.square(); if ('' === square() && !this.winner) { square(this.xIsNext ? 'X' : 'O'); } } }); SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 61. 1. Shared state in DOM or UiComponents Strong coupling through cross-component dependencies SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 62. 1. Derived state In this approach state derived from one model is o!en stored in another model SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 63. 1. Derived State updateFoo: function() { this.foo = this.other.bar * this.other.bar; } // vs. foo: function() { return this.other.bar * this.other.bar; } SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 64. 2. Pass state from root down to children E.g. pure react components Works within one component hierarchy SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 65. 2. Example from React TicTacToe <Board squares={current.squares} onClick={i => this.handleClick(i)} /> class Board extends React.Component { renderSquare(i) { return ( <Square value={this.props.squares[i]} onClick={() => this.props.onClick(i)} /> ); } SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 66. 2. Pass state from root down to children Problem when state is required outside one hierarchy SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 67. 2. Pass state from root down to children Not common in Magento 2 SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 68. 2. Pass state from root down to children No callback on parent, only on child Component.extend({ initContainer: function (parent) { const state = parent.state; this.cells = [...state.squares.keys()].map(function (i) { return new Square({index: i, state: state}); }); return this._super(parent); } ... } SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 69. 3. Keep state outside the view E.g. Elm architecture, flux, redux/vuex Most versatile but needs more plumbing SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 70. 3. Keep state outside the view There are differences: Naming, (im)mutability, 1 or 2 way data flow, (F)RP, effects handling, amount of architecture... But there always is a single state storage SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 71. 3. Separate state with UiComponents State object with observable properties define(['ko'], function (ko) { 'use strict'; return ko.track({ moves: [], squares: [...Array(9).keys()].map(() => ko.observable('')), xIsNext: true, winner: false }); }); SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 72. 3. Separate state with UiComponents Require and use state container object define( ['uiComponent', 'ticTacToeState'], function (Component, state) { 'use strict'; return Component.extend({ ... handleClick: function () { if ('' === this.value() && !state.winner) { state.squares[this.index](state.xIsNext ? 'X' : 'O'); } }, }); } ); SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 73. Example Breakout https://github.com/Vinai/example-module-breakout SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 74. 3. Multiple state storage objects define( ['gameComponent', 'ballState', 'frameState', 'gameState'], function (GameComponent, ball, frame, game) { 'use strict'; return GameComponent.extend({ initialize: function () { this._super(); this.initDimensions(frame); frame.width = function () { return game.width * .98; }; frame.height = function () { return game.height * .80; }; frame.left = function () { return game.width * .01; }; frame.top = function () { return game.height * .19; }; }, ... SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 75. 3. State outside the view Benefits: — State is simple to share — View models contain mostly only logic — Less code — Easier to understand — More maintainable SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 76. Recommendations for maintainable UiComponents... SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 77. The code needs to... 1. Pass all tests 2. Reveal intent 3. Contain no duplication 4. Have the fewest possible elements 5. Separate shared state from the view SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018
  • 78. Thanks to Kent Beck for his timeless 4 rules of simple design. Thank you for your attention! SOS UiComponents - (c) @VinaiKopp - for #MageTitansIT, Milano, 06. April 2018