Migration from 6.5.x to 6.6.0

1) Adding a component using the code

If you want to create a component in runtime and add it to your page, following example provides a guidance:

JavaScript
JavaScript
const myPage = extend(myPageDesign)(
function(_super) {
_super(this);
// Add new Button
var myButton = new Button();
// 3rd parameter is optional and is used to give class name
// 4th parameter is optional and is used to give user properties
this.addChild(myButton, "myButton", ".button", function(userProps) {
userProps.width = 500;
return userProps;
});
});

or

JavaScript
JavaScript
this.addChild(myFlexlayout, "myFlexlayout", ".flexlayout", {
top: 60,
height: 10,
flexProps: {
alignSelf: "CENTER",
positionType: "ABSOLUTE",
}
});

There is another way of adding component in runtime using the addChild as an action. Detailed example can be found under Adding a child to a ListViewItem using the code.

Warning

Assume you have an instance of FlexLayout which hasn't been attached with context. If you add some children to it using addChild method, those children won't be attached with context. (Even though you attach your FlexLayout instance afterwards)

The only way of doing this, is to attach your FlexLayout instance with context first, then add children to it. Then all of your components will be attached with context.

2) Custom properties using the code

If you want to assign custom properties using the code, you can use component.dispatch as follows:

Before

JavaScript
JavaScript
this.marginTop = 5;

After

JavaScript
JavaScript
this.dispatch({
type: "updateUserStyle",
userStyle: {
marginTop: 5
}
});
// Perform this when position related properties to be changed
page.layout.applyLayout();

3) Adding a child to a ListViewItem using the code

Before

JavaScript
JavaScript
myListView.onRowCreate = function() {
var myListViewItem = new MyLibraryComponent();
return myListViewItem;
});

After

JavaScript
JavaScript
const addChild = require("@smartface/contx/lib/smartface/action/addChild");
var itemIndex = 0;
myListView.onRowCreate = function() {
var myListViewItem = new MyLibraryComponent();
this.dispatch(addChild(`item${++itemIndex}`, myListViewItem));
return myListViewItem;
});

If you want your component to be attached to context and your component's parent has already been attached to context then addChild action for your component will be sufficient to perform the attachment.

In this example, note the myListview_onRowCreate method. this object has already been attached to context and we want to attach our "ListViewItem"s. Note that this component here denotes ListView.

JavaScript
JavaScript
const addChild = require("@smartface/contx/lib/smartface/action/addChild");
this.invalidateListView = invalidateListView.bind(this, this.myListview.onRowCreate);
function invalidateListView(originalOnRowCreate) {
this.myListView.dispatch({
type: "removeChildren"
});
var itemIndex = 0;
this.myListview.onRowCreate = function myListview_onRowCreate(superOnRowCreate) {
const myListViewItem = originalOnRowCreate.call(this);
this.dispatch(addChild(`item${++itemIndex}`, myListViewItem));
return myListViewItem;
};
}

5) getCombinedStyle (deprecated)

Before

JavaScript
JavaScript
var myButton = new Button();
var activeStyle = getCombinedStyle(".item.active");
var passiveStyle = getCombinedStyle(".item.passive");
if (state === "active") {
// myButton will have properties of ".item.active"
Object.assign(myButton, activeStyle);
}
else {
// myButton will have properties of ".item.passive"
Object.assign(myButton, passiveStyle);
}

After

JavaScript
JavaScript
const pushClassNames = require("@smartface/contx/lib/styling/action/pushClassNames")
const removeClassName = require("@smartface/contx/lib/styling/action/removeClassName")
var myButton = new Button();
if (state === "active") {
myButton.dispatch(pushClassNames(".item.active"));
}
else {
myButton.dispatch(removeClassName(".item.active"));
}

Actions Used

pushClassNames Pushes new class names to the related component's list of class names then it will be rendered with the new properties. removeClassName Removes a class name from the related component's list of class names then it will be rendered with the new properties.

Performance Considerations

Although being a handy concept, overusing removeClassName could cause performance issues.

6) Adapting miscellaneous components

These miscellaneous components are SliderDrawer, BottomTabBar and some others. These are designed within the library and not available in the UI editor.

SliderDrawer

Before

JavaScript
JavaScript
// scripts/components/SliderDrawer.js
const SliderDrawer_ = extend(SliderDrawer)(
function(_super, props, pageName) {
// Other code
});

After

JavaScript
JavaScript
const componentContextPatch = require("@smartface/contx/lib/smartface/componentContextPatch");
const SliderDrawer_ = extend(SliderDrawer)(
function(_super, props, pageName) {
_super(this, props);
componentContextPatch(this, "sliderDrawer");
});

BottomTabBar

Suggested Usage

JavaScript
JavaScript
const TabBarItem = require('sf-core/ui/tabbaritem');
const BottomTabBar = require('sf-core/ui/bottomtabbar');
const Navigator = require('sf-core/ui/navigator');
const componentContextPatch = require("@smartface/contx/lib/smartface/componentContextPatch");
const pushClassNames = require("@smartface/contx/lib/styling/action/pushClassNames");
BottomTabBar.$$styleContext = {
classNames: ".tabs__bottomTabBar",
userProps: {}
};
const tabs = exports.tabs = new BottomTabBar();
tabs.children = {};
const dashboardNavigator = exports.dashboardNavigator = new Navigator();
dashboardNavigator.add("dashboard", require("./pages/pgDashboard"), true);
dashboardNavigator.go("dashboard");
tabs.children["dashboard"] = new TabBarItem({
title: "Dashboard",
route: dashboardNavigator
});
tabs.children["dashboard"].dispatch(pushClassNames(".tabs-dashboard"));
tabs.add("dashboard", tabs.children["dashboard"]);
const settingsNavigator = exports.settingsNavigator = new Navigator();
settingsNavigator.add("settings", require("./pages/pgSettings"), true);
settingsNavigator.go("settings");
tabs.children["settings"] = new TabBarItem({
title: "Settings",
route: settingsNavigator
});
tabs.children["settings"].dispatch(pushClassNames(".tabs-settings"));
tabs.add("settings", tabs.children["settings"]);
// Run this only after adding components to tabs' children
componentContextPatch(tabs, "bottomTabBar");
tabs.setIndex("dashboard");

7) Adding custom page to context

If you created a page from code, not from UI editor this section explains how to perform integration with context.

JavaScript
JavaScript
const extend = require('js-base/core/extend');
const PageBase = require('sf-core/ui/page');
const Page = extend(PageBase);
const pageContextPatch = require('@smartface/contx/lib/smartface/pageContextPatch');
function $NewPage001(_super, props) {
_super(this, props);
this.children = {};
this.children["statusBar"] = this.statusBar;
this.children["headerBar"] = this.headerBar;
pageContextPatch(this, "newPage001");
// You may override onShow, onLoad after pageContextPatch is called (optional)
}
$NewPage001.$$styleContext = {
classNames: ".page",
userProps: {},
statusBar: {
classNames: ".statusBar",
userProps: {}
},
headerBar: {
classNames: ".headerBar",
userProps: {}
}
};
const $NewPage001_ = Page($NewPage001);
module && (module.exports = $NewPage001_);

8) Subscribing context (advanced use case)

When your component's styles are changed, for example, if you set different styles for different rotations for your component using rules and you rotated your device, then subscribeContext is called to inform you that styles have changed regarding your component's class name. In this example note the .flexLayout:

JavaScript
JavaScript
const addChild = require("@smartface/contx/lib/smartface/action/addChild");
const createSFCoreProp = require("@smartface/contx/lib/smartface/sfCorePropFactory").createSFCoreProp;
page.dispatch(addChild("myChild", {
subscribeContext: function(e) {
if (e.rawStyle.backgroundColor) {
// Get color object
var backgroundColor = createSFCoreProp("backgroundColor", e.rawStyle.backgroundColor);
}
}
},
".flexLayout"
));

Notes

  • Do not call dispatch before onLoad method of page is called. (For example in constructor it cannot be called)

  • defaults property of the Library components no longer exists

  • Please make sure that you're using latest node modules. For example version of js-base must be at least 1.0.4

Additional Information

For more information and advanced usage please refer to the Contxjs documentation