First of all, the ExtJS version I'm using is version 4.2.
I have a parent component that has multiple children (let's say there's 3 children) that extend from it and therefore modify it.
I now wish to have a new component that will have to pass through one of the other 3 children (it can be any of them) and finally that one child that the new component called, would call the parent.
It's a bit difficult to explain this scenario so to better visualize it, it would be something like this:
NewComponent_| > ChildComponent1 > | ParentComponent
______________| > ChildComponent2 > |
______________| > ChildComponent3 > |
The parent component is a simple popup that the children modify.
The new component is also intended to modify the parent popup however it can't prevent the children to modify it as well.
If I just had one child component, I would simply extend it in the new component and that's it but because I have multiple I'm not really sure what the most appropriate course of action should be.
I thought about trying something like dynamically extending a given child, I'm not sure if that would work.
Also, is there something like multiple parents in Ext? I'm a relative newbie so I really don't know.
Any help would be appreciated and if you need further clarification please say so.
I think you should rethink your structure.
First, you cannot change/set class inheritance dynamically. But I think your problem is simpler than it seems.If I got it right, you have a parent window (modal) that holds some fields or information. If you call any of the three child classes, it overrides/extends that parent, which means you can forget about it. Now you are only dealing with the selected child class.
I guess you have some kind of a view on the base level, a grid or a panel, that then invokes on a - let's say - click event that child class.
So I think what you're looking for is something like this:
Ext.define('App.ParentModal', {...});
Ext.define('App.Child1', {
extend: 'App.ParentModal',
...
});
Ext.define('App.MyPanel', {
...
items:[
{
xtype: 'button',
handler: function() {
if (condition1) {
Ext.create('App.Child1');
// call child1 that modifies parent the way you want
return;
}
if (condition2) {
Ext.create('App.Child2');
// call child2 that modifies parent the way you want
return;
}
}
}
],
...
});
I hope I could help.
Related
I want to get an event that is fired relatively on the top of the dom-hierarchy to a child component further down the hierarchy.The child is not a direct child of the parent
I understand that I do that with the input-decorator. Please note doing it the other way around like it should be is not possible.
The html of the parent looks like this
<element [data]="viewData" (anext)=OnNext($event)></element>
I need to get the $event available in the child. How do I achieve this?
You can create a service with an rxjs Subject, as shown in the psuedo code below.
//Evservice.ts
public subject = new Subject();
OnNext(event) {
subject.next(event)
}
//childComponent.ts
constructor(ser: Evservice)
ser.subject.subscribe((ev) => {//access your event here});
The following is my component tree.
DashboardComponent
TaskManagementView
TaskManagementForm
SubmitButtonComponent
I need to pass the button clicked event from SubmitButtonComponent to the DashboardComponent.
One way of doing this would be as follows
<DashboardComponenet AddTask={AddSomeTask}>
....
<TaskMangementView submitClicked={props.AddTask}>
....
<TaskManagementForm ButtonClick={props.submitClicked}/>
.....
<SubmitButtonComponent onclick={props.ButtonClick}/>
....
<TaskManagementForm />
....
</TaskManagementView >
....
</DashboardComponent>
Is there some good way of passing the onClick to the DashboardComponent ? This is hard to maintain.
As Gaurav said, you can either pass the function down through the components as props. But this can get messy when there are many components in the middle
OR
I would recommend using something like Context which will allow you to skip components in the middle and just access the function where needed.
Is it possible for a React component's parent to be unmounted without the child being unmounted? What work arounds exist to achieve this result? Surely there must be some (potentially hacky) way to do this.
Example
When this:
<Parent>
<Child/>
</Parent>
changes to this:
<Child/>
I would like Parent's lifecycle method componentWillUnmount to be called without Child's lifecycle method componentWillUnmount being called.
I recognize this may not be possible but was wondering if anyone had a creative solution to this problem.
Update
Here's my specific use case (hopefully I do a good enough job explaining this):
I have a higher order component which doesn't introduce any new dom elements but essentially just introduces some new context for the child component. The child component renders slightly differently depending on whether or not this context is present. Unfortunately when I remove and add the parent a new instance of the child is created and it unmounts/remounts. The only issue with this unmounting and remounting is that the child element does some dom measurements to decide whether or not to show a horizontal scroll bar and overflow menu for some of it's elements. When it unmounts/remounts there is an unsightly flash of this menu.
You could handle the rendering logic. For example inside your render function:
if (showParent) {
return (
<Parent>
<Child/>
</Parent>);
} else{
return <Child/>;
}
Then whenever the boolean showParent changes the component renders differently.
The super-parent object, calling this render() , should store the state in order to update them and preserve the child (and parent, in case you want to switch it back on).
Therefore it should also contain the state of the child, in order for it to be kept. In other words: move the model hierarchically up to the super parent.
I use Polymer, Html and Javascript.
I want to find any easy way to call a function from one polymer component to another.
Let me describe what I want to achieve.
I have polymer component myComponent. In this component container with button called start:
<button on-click="_start" id="start">XyZ</button>
and also second component (let's say it is child component, because it is in myComponent, where I have got function _addNew in <script> section.
Now I want to fire _addNew function by clicking button with #start id.
My question is how can I call a function from one polymer component when this function is placed in another?
I hope you understand me.
if I understood correctly, basically what you want to do is fire from one component and listen in the other one.
So you fire from myComponent, in the _start method like:
this.fire('add:new');
and then to listen to the add:new event in your other component by adding a listener, for this specific event name:
listeners: {
'add:new': '_addNew'
},
if it's not explicit enough, please do read the Polymer documentation it's a very nice and well explained documentation.
Hope it helps.
In my case this is not working, because this.fire is going "up", to the parent component, not to a child component.
In my case this one help:
this.$$('component-name').function-name();
We're creating a new site and we chose reactjs to do this. And right now I'm researching on events in Javascript and luckily I stumbled on this site where he teaches how to handle events for many elements and letting the parent handle the event and basically is what we are doing for out site as well right now.
As I continued to research, I also stumbled upon this answer here (more react oriented) where it says I would pass the function/method from the parent to the child.
Is it promoting the same way as what was mentioned on the first link? Also, is this the way to do this (like the first link to handle events) in reactjs? Should I implement somewhere along this lines?
Follow up question... or should I ask this separately?
If I have
<Parent>
<ChildComponent>
<ChildComponent>
...
and a child when clicked I add a class to it, say .selected. But I'd need to remove it to the others since they are not selected anymore. In jQuery I could've done something like
$('.child-components').removeClass('selected');
$(this).addClass('selected');
How to do this the react way?
For your first question, it would depend on the exact situation and the relationship between the parent and child component.
For example, handling a click event for one child component (out of many similar others under the same parent) would be better done by the parent.
But as a counterexample, consider a component that's a text input. It might perform its own validation before passing it to the parent (which could be the form that handles submission), in which case handling the change events would be better done within the component itself rather than by the parent.
In general, yes, the React way to handle events is to pass the event handler functions from parent to child as necessary.
For your second question, you just need to store the index (or some other ID) of the selected child component in the parent's state. Then, in the parent's render method (where I assume the child components are also rendered), use that information to add the .selected class to the proper child component. So the parent knows which child is selected, and takes care of rendering them properly.
The other way around, you can then update the parent's state based on child events (e.g., setting selection when a child is clicked) by using a click handler function passed from the parent to the child via props.
Hope this helps!
The article you mentioned is using event bubbling. It attaches one event handler, and lets all events bubble up to it. It's a very good approach, and it's actually what React does internally. It only seems like you attach event handlers directly to an element when you do <div onClick={this.handleClick} /> but what React does is to only set up one click listener for the top node. It only calls your this.handleClick if that event bubbled up to that element.
For your second question, you would do something like this:
var Child = React.createClass({
render: function () {
return <li className={this.props.className} onClick={this.props.onClick}>{this.props.text}</li>;
}
});
var Parent = React.createClass({
getInitialState: function () {
var items = [
{text: 'One'},
{text: 'Two'},
{text: 'Three'}
];
var selected = items[0];
return {
items: items,
selected: selected
};
},
handleClick: function (item) {
this.setState({selected: item});
},
render: function () {
var self = this;
return (
<ul>
{this.state.items.map(function (item) {
return (
<Child
key={item.text}
className={this.state.selected === item ? 'selected' : ''}
onClick={self.handleClick.bind(self, item)}
text={item.text}
/>
);
})}
</ul>
);
}
});
Here's a working JSBin: http://jsbin.com/libunecaba/1/edit?js,output