Is calling doLayout() method a must after adding child to a parent? - dynamic

In our application, there is a tabpanel in which we are adding/removing the panel dynamically.
The panels get added at the click of a menu item by the following code in menu handler:
Ext.getCmp('mainTabPanelId').add(getPanel());
Here getPanel() method returns the panel after creating it.
Assuming that the id of main tab panel is mainTabPanelId and that of the child panel is panelId, in this context, could someone guide at the following:
Is it necessary to call doLayout() on mainTabPanel after the add method?
Should the doLayout() be called on the mainTabPanel or on the newly added child panel, that is, Ext.getCmp('mainTabId').doLayout() or Ext.getCmp('panelId').doLayout()?
Will a call to doLayout() take care of all the issues related to rendering, like scrollbars esp.?
The method getPanel() should return an already created panel (using Ext.create) or should it return a config object (having xtype:'panel')? Which one should be preferred for better performance keeping time in mind?

AbstractContainer::add()
<...> If the Container was configured with a size-managing layout manager, the Container will recalculate its internal layout at this time too.
So you don't have to do 1 — 3 because:
AbstractContainer::doLayout()
<...> The framework uses this internally to refresh layouts form most cases.
AbstractContainer::defaults
For defaults to work, the child items must be added using {xtype: ......} NOT using Ext.create("widget.type",{}) © roger.spall
So I'd prefer return configuration object instead of components itself.

Related

Maintaining view state when navigating to another view

I have one VuesJS view with two components in it that have a main-detail relationship. The user can click on an item in the main component (the item gets highlighted) and the details component will show the related detail items.
products.vue
<main></main>
<details>></details>
The user can edit a detail item and I want that to take place using a separate view containing the necessary components to edit the detail item.
I want the user to be able to navigate back to the products.vue view (say after finishing the editing process) with its state as it was when the initiated the editing operation.
I tried wrapping each of main and details in <keep-alive></keep-alive> but that did not seem to do the trick.
I have also read a few posts where <keep-alive></keep-alive> is used with the include property around the <router-view></router-view> but I'm not sure what to include in the include in my case.
Any thoughts on whether this is possible or what I'm doing wrong?
thanks
To persist state beyond route changes the state needs to either be stored:
in a component that is a parent to the <router-view> (such as <App>)
in a new vue instance with shared state that you import into the required components
in the official state management library Vuex (recommended)

Attach/Render RactiveJS component outside of template

I've got an existing SPA that was developed using nested RactiveJS components. Which is great, and offers a ton of flexibility throughout the entire app. Currently I attempting to add in client side routing support using page. My navigation switches out high-level components using simple {{#visible}}{{/visible}} template markup on each component. This is a little troublesome in its current state as it always kicks off a re-render whenever the high-level component becomes visible again.
Is there a way to render a component, for example, called widget, without using the
<widget></widget>
method? I've already "registered" the component with the parent, but obviously when constructing it by means of
new App.components.widget
I am able to control how/when it's rendered/inserted/detached, but lose the recognition in the application's component hierarchy.
There is insert exactly for that. You don't even need to "register" it to the component you plan to put it to. You can use the different find* methods or nodes to easily retrieve a reference of your planned container element.
var instance = new YourDetachedWidget({ ... });
instance.insert('#your-container'); // This could be a node, selector or jQuery object

Dojo dijit tree hide expand icon

I've got a dijit Tree which is populated via a store wrapped in Observable, essentially the example here: http://dojotoolkit.org/reference-guide/1.10/dijit/Tree.html#id7 (Not that the example actually runs from the dojo site though: unless that's just my browser).
It's working well and I can expand and collapse items. However, it displays an expand icon even for the last item in a hierarchy - i.e. an item that doesn't have any children. When you try and expand such an item, it seems to realise this and the expand icon then disappears.
Does anyone know of how to supress the expand icons from appearing in the first place?
Thanks!
Implement the mayHaveChildren() method of the model:
Implementing logic here avoids showing +/- expando icon for nodes that
we know don't have children. (For efficiency reasons we may not want
to check if an element actually has children until user clicks the
expando node)
This method inputs one of your items and outputs true if it can be expanded; false otherwise.

Make button text A/B testable - Sitecore MVC

I have an MVC/angularJS page with a button, the button needs to call code to process the current page and proceed to the next step in the application, but they want the button text to be a/b testable with different variations. I'm new to Sitecore so am struggling to know the best way of doing things.
I thought of having a simple text component/template which just has a single line text property, but if I add that to the page template then it doesn't seem a/b testable because when you click on the test option it asks you to select content. Whereas the content was text they entered as part of the page template.
The only way I know of making a/b testable content so that they can click on the page in page editor and choose to select content / add test variation. I wouldn't add the button to the placeholder as it needs to call specific angular code and always be there, but should I be adding a placeholder where the text is? It seems like overkill to have to define a placeholder there, define a rendering, create a partial view, define placeholder settings to limit it to the simple text component, and then hope they don't try adding multiple items to the placeholder.
I would make a separate template (ie with the text field for your button) to represent your form, then either create the two test variation items as children of your page, or maybe place them in a shared components folder outside of your 'home' node.
EDIT
In order to move your form component into a new A/B testable component you would need to create a new Sublayout in Sitecore, then create a new ascx control for the sublayout. In the Page_Load handler of this control, you would use the following code to retrieve the datasource of the sublayout:
//assume you have a button on your usercontrol called btnSubmit
//assume your template has a single-line text field called 'SubmitButtonText'
Guid dataSourceId;
Sitecore.Data.Items.Item dataSource;
if (Guid.TryParse(sublayout.DataSource, out dataSourceId))
{
dataSource = Sitecore.Context.Database.GetItem(new ID(dataSourceId));
btnSubmit.Text = dataSource["SubmitButtonText"];
}
So I created a new template which just had a single line of text as a field, and added a content item in a shared data node.
In my partial view:
#model Digital.Models.SimpleTextItem
<button ....>
<span class="hidden-xs">#Model.SimpleText_Value<br></span>
</button>
In my main page - I was trying to statically bind it so that they could only change content rather than add new controls to the placeholder, but that only worked if I specified the datasource in this page.
Using a rendering, and in the page layout adding the rendering to the placeholder with a specified data source:
#Html.Sitecore().Placeholder("PremiumQuoteApplyNowPlaceHolder")
Not sure if it was the best approach but it achieves what I need it to.
A/B testing could be applied only to controls(XSLT renderings, sublayouts, action controller renderings, view renderings). If you want to make A/B testing only for button then you should create additional control for it as you did.
Technical details for MVC: A/B testing is applied on mvc.customizeRendering pipeline where rendering arguments are processed. This pipeline operates on renderings level. It means that you are not able to create A/B testing for particular field(button) without your own customization.

layout doesn't work when adding nodes to graph dynamically

When I add nodes to the graph statically via the elements property of
$('#cy').cytoscape(..)
the layout option works but when I add them via
cy.add({..})
the layout is ignored. I can apply new layout only on these events(click, mouseover, mouseout) like this:
cy.on('mouseover', function(event) {
cy.layout({name: "grid"});
});
and the layout changes. Tried with other events: ready, done and load but it doesn't work.
Is there a normal way way to change the layout when elements are added dynamically?
You can't call a second layout while the initialisation layout is running. Configure your initialisation properly (http://cytoscape.github.io/cytoscape.js/#core/initialisation) to have all the data and options you require.
As for cy.add(): Don't try using cy.add() on load unless you specify everything you need (incl. position) for those elements. Or, you'll have to at least wait for layoutstop before running a new layout. In general, you're better off using the initialisation options to do things for you rather than having to worry about edge cases and event synchronising yourself.