Add ExtJS components at run time - "refresh view"? - javascript

I am adding components to a panel at runtime:
Ext.define("MyApp.view.SomePanel",{
extend:'Ext.panel.Panel',
...
setGridList:function(gridIds) {
myItems=[];
Ext.each(gridIds,function(gridId){ myItems.push(Ext.getCmp(gridId) || Ext.create("Ext.grid.Panel",{id:gridId}))});
Ext.applyIf(me,{items:myItems});
}
});
It works well when called for the first time, from the initComponent. But it does not work when called from a store load handler. My best guess is that I have to refresh the view, rebuild the layout or sth. like that!? But I don't find such a thing in the docs.
Anyone here knows the trick?

If your class MyApp.view.SomePanel is an Ext component, than you could use the Container.add() or Container.remove().
If the child is not automatically added, call the Container.doLayout() method.
PS: the layout of your class should support multiple children.

Related

Fullcalendar v5 eventContent not working with angular js

I'm using Fullcalendar v5 in angular js, and i'm trying to make a custom event with:
https://fullcalendar.io/docs/content-injection
eventContent: function(arg) {
return { html: constructEvent(arg) }
},
The thing is that if i add:
"<div ng-repeat='user in arg.event._def.extendedProps.users' class='avatar'>"
"<p>{{ user.name }}</p>"
"</div>"
it won't render. It's like it's outside angular's scope. Can someone tell me if there is a way to construct this with angular js logic? Or i need to use vanilla js to iterate through items. Also ng-click doens't work. I tried even with triggering safeApply digest but no results.
I just want to edit the event inside calendar with the framework i'm using, and use angular events inside it to open sidebars or to make api calls.
Rendering Events
with your line <div ng-repeat it seems that you'd like to iterate through an array of events to display on your screen. If this is the case, you simply need to render the events via the 'events' parameter.
https://fullcalendar.io/docs/event-object
Regarding eventContent (the contents of an event, such as title, subtitle, img, etc)
It looks like at the minute only React JSX Nodes are supported. Vanilla JS is your only way forward.
https://fullcalendar.io/docs/content-injection

How to inspect element of Zebkit UI

As part of automation testing, we want to inspect the element in a website which is made of using the Zebkit UI framework.
We are unable to find the element using zebra.ui
examples can be found here
Can someone help us on inspecting the element
Zebkit UI components are rendered on HTML5 Canvas. So they are not part of browser DOM tree what can be a problem for a test tool that expects DOM as an input. But it doesn't mean you cannot go over zebkit UI stuff to perform test cases.
First of all keep in mind zebkit components are a hierarchy/tree like DOM is. Every rendered on a canvas zebkit UI component has a related JS instance of appropriate class. There are number of API methods you can use to travel over UI components tree. These methods expect path (XPath-like) since path (from my point of view) is less "encrypted" way than CSS selector.
The API methods you probably need:
byPath(path [,callback]) - traversing UI components tree by the given path
var zcanvas = new zebkit.ui.zCanvas();
...
// travel over all UI components in tree
zcanvas.byPath("//*", function(comp) {
// perform test cases here
...
});
properties([path,] properties) applies the specified properties set to component or number of components requested by the given path
var zcanvas = new zebkit.ui.zCanvas();
...
// set color property to black value for all labels
zcanvas.properties("//zebkit.ui.Label", { color: "black" });
on([eventName], [path], handler) add listener method(s) for the given event (or all events) of the given component or components identified with the path:
var zcanvas = new zebkit.ui.zCanvas();
...
// register event listener for all found buttons
zcanvas.on("//zebkit.ui.Button", function (src) {
// handle button press event here
...
});
fire([eventName,] [path,] [argument]) fire the given event to the given component or to components identified with the path:
var zcanvas = new zebkit.ui.zCanvas();
...
// fire button pressed event to button with id equals "testButton"
zcanvas.fire("//[#id='testButton']");
...
// or the same with a shortcut
zcanvas.fire("#testButton");
I'm not sure I understand correctly your issue, but assume you cannot click right button on canvas to open context menu and select "Inspect element" option.
You can
press F12 in browser
switch to "Elements"/"HTML" tab
in search field (CTRL + F) print "canvas"/"<canvas" and press Enter
Continue pressing Enter until required canvas found (current element should be highlighted)
These controls are implemented using an HTML5 CANVAS tag. Selenium cannot see "inside" this tag because it doesn't contain HTML. It's like an app inside the page. From the page you linked, it looks like you should be able to use JS to access elements inside the control. When I've done things with CANVAS tags in the past, I generally find JS that does or returns what I want and then wrap that code in a function that I can call. It will work but you will likely have to do some research on Zebkit to find out what JS you will need to validate, etc. all the different things you will want to validate... and it may end up that you won't be able to validate some things.

How can I get React to Replace (not Merge) VDOM?

I have a component which, in componentDidMount, gives a jQuery plugin some control over the DOM rendered by React. I know everyone says "never let anything but React touch the DOM", but hear me out, as reinventing this plugin is not feasible right now, and I think there should be an "overwrite whatever you find in the DOM" switch for React that I hope someone can point me to.
More info: I've designed it so the state of the React's DOM is entirely determined from the props given to React except while the user is dragging things around. Once dropped, I don't care how the DOM changed since the last React update, I just want to render everything from the current props of React, which I am passing in on the plugin's change handler via ReactDOM.render
The symptoms are that the nodes created by the plugin during and after dragging don't go away after React is told to update!
Yes, the nodes are key-ed initially.
The plugin is Nestable, and it adds interactivity (drag-drop reordering of the tree), and a JSBin is here: http://jsbin.com/qareki/edit?js,console,output
I'm really looking for the "Kill whatever you find" setting. I thought calling ReactDOM.render would do it, but it's clearly not doing it. Neither of course, was the more surgical setState, but I didn't expect it to. Thanks in advance for all 'you're doing-it-wrong' advice and other fixe
Manually add a div element in componentDidMount and replace it with a new one in componentDidUpdate:
class Foo extends React.Component {
render() {
// whatever HTML you want...
return (
<div>
<div>
{/* this div will contain our non-React stuff that we need to reset */}
<div ref="container"></div>
</div>
</div>);
}
blastAndRecreate() {
// throw away any content within the container and replace it with brand new content
const container = $(this.refs.container).empty();
const newDIV = $("<div>").appendTo(container);
// give this new DIV to nestable plugin
newDIV.nestable(...);
}
componentDidMount() {
this.blastAndRecreate();
}
componentDidUpdate() {
this.blastAndRecreate();
}
}

angular 2.0 mandatory refresh like $apply

I am create an app to drag a component(angular2 component, same below) from a list and drop it into another component. In this process I used interactjs to drag and drop component. But when I drop it into another component, It only load the static html in the component template which dragged.
For example I have this component to be added into another
import {Component, View} from 'angular2/angular2'
#Component{
selector:"sample"
}
#View{
template:`<p>static content</p><p>{{contentToBind}}</p>`
}
class Sample{
contentToBind:string= "I am the binding content."
}
when it added, it should looks like below
static content
I am the binding content.
But actually it just display static content like
static content
You can check this example in this plunker.
And then I bind a click HostListener to this Sample component, when I click the component has been already added into another component, "I am binding content" will appear(other event triggered is same).
I think due to interact it has jumped out of angular2's lifecycle.
Any similar method as $apply() in angularJs 1.x?
Interact is not a part of angular 2, maybe your code in Interact is out of angular 2 scope as you said.
You can use NgZone in your Interactjs file in plunker, I edit your code and it's worked now. You should send your event inside of NgZone.
something like this.
myParent.ngZone.run(
() => {
console.log("onDrop...");
ce.drop("Hello");
}
);
See it on plunker
Plunker

Angular 2 add custom component to Owl Carousel 2

I have created two components in Angular 2:
ReaderComponent: The one that initiates and controls all functionality to Owl Carousel (initiate, add slide, remove slide and so on)
PageComponent: Each slide is a PageComponent and has events to handle input from the user (click, pinch, doubletap)
The ReaderComponent is created at start of the application and initiates a request to a service to get all data for each of the PageComponents.
Everything works fine until we add a slide that is a PageComponent. I have tried to add the PageComponent selector to owl Carousel:
this.slider.trigger("add.owl.carousel", ["<my-page-component></my-page-component>"]);
This does add an element of <my-page-component> but does not render the template or handles any of the PageComponents events.
I have tried to add all the PageComponents to an array and render it in ReaderComponents template:
<div *ng-for="#page of pages">
<my-page></my-page>
</div>
This renders correct but by that time all pages is rendered Owl is already initiated and no pages is visible.
So to summarize all of this: I need to know how to add a custom component via javascript (in this case the add functionality of Owl)? Is this even possible? Or is there another way to handle this so that I can add PageComponent in any way?
The first method you mentioned would require you to force angular to re-check it's bindings. This is probably possible, but I don't know off the top of my head.
The second method is much easier. You can use the lifecycle events of the Page or Reader Components to trigger the adding. They are as follows:
export var LIFECYCLE_HOOKS_VALUES = [
LifecycleHooks.OnInit,
LifecycleHooks.OnDestroy,
LifecycleHooks.DoCheck,
LifecycleHooks.OnChanges,
LifecycleHooks.AfterContentInit,
LifecycleHooks.AfterContentChecked,
LifecycleHooks.AfterViewInit,
LifecycleHooks.AfterViewChecked
];
If you add a listener to your PageComponent class, you can probably use OnInit or AfterViewChecked and then get it to add it's own element reference to the carousel (basic example). From a quick look at their documentation, it doesn't look like owl supports adding a new element, so you could have the PageComponents all on your page somewhere hidden and then just add the raw html from the elementref, then remove it again in the OnDestroy function.
If you do it in ReaderComponent you should look at OnChanges or add some clever checks into the DoCheck function and then just get it to reload all items inside it (perhaps owl.reinit?). I've not used the owl carousel before so can't be more specific there I'm afraid.
These are exported from the angular class as interfaces, so you should be extending your classes from them. An example is available on the Angular 2 website here: https://angular.io/docs/ts/latest/api/lifecycle_hooks/AfterViewChecked-interface.html

Categories