Some questions about backbone.gepetto plugin
I have a layout and some view inside. How to pass view generated event to layout ? Instance view in layout:onRender, pass parentContext to view, and use this.context.dispatchToParent to send message to layout or listen view.context events in layout ? What strategy is better: parent listens child or child sends event to parent (says, render me) ?
In geppetto examples I saw only one context per one view, but not a one context to many views, how to share code and data between widgets?
When to use dispatch, dispatchToParent, dispatchGlobally ?
What is main idea of context ? Without context, widget can listen events, can send them to parent or parent can listen them like context, what difference ?
How to determine what logic should be in the context and what in the view item ?
Geppetto author, here. I've responded to this question in the GitHub repo issues list. See here: https://github.com/ModelN/backbone.geppetto/issues/5#issuecomment-11155226
Related
I have one quick action which opens up the aura lightning component. In that I have one requirement to execute some logic when the quick action is closed by "X" close button on the top right corner(not by cancel button).
I was searching so many articles most of them explained about closing the quick action by clicking the cancel button. I would like to know whether we can write some logic when quick action is closed by "X" close button or is there any way we can capture the onClick event for this close button.
I couldn't share any code snippets because I have not written any, still I am searching for solutions.
Have you seen the aura component lifecycle, especially stuff around (re)rendering the component? You could attach what you need to "unrender" call.
Put this in myComponent/myComponentRenderer.js and try?
({
unrender: function () {
this.superUnrender();
alert('You\'re closing me, I thought we were friends');
}
})
Alternatively have a look at handling aura:valueDestroy. I mean renderer should just try to clean some custom DOM stuff, free memory maybe, shouldn't run business logic. If there's a more appropriate system event - maybe play with that one?
Have you tried creating a custom event to handle this?
Reference: Lightning Aura Components Developer Guide: Create Custom Component Events
Create a custom component event using the <aura:event> tag in a .evt resource. Events can contain attributes that can be set before the event is fired and read when the event is handled.
Use type="COMPONENT" in the <aura:event> tag for a component event. For example, this c:compEvent component event has one attribute with a name of message.
1. <!--c:compEvent-->
2. <aura:event type="COMPONENT">
3. <!-- Add aura:attribute tags to define event shape.
4. One sample attribute here. -->
5. <aura:attribute name="message" type="String"/>
6. </aura:event>
7.
The component that fires an event can set the event’s data. To set the attribute values, call event.setParam() or event.setParams(). A parameter name set in the event must match the name attribute of an <aura:attribute> in the event. For example, if you fire c:compEvent, you could use:
1.
2. event.setParam("message", "event message here");
3.
The component that handles an event can retrieve the event data. To retrieve the attribute value in this event, call event.getParam("message") in the handler’s client-side controller.
Say I am building an instant messaging with app with React (I'm not doing that exactly, but this is easier to explain). I have a sidebar with a list of conversations and, when you click one, it is shown on the right (similar to this). I don't want to mount each conversation component until the user clicks it, but I don't want to unmount it, just hide it, when they click on another conversation. How can I do this cleanly? There will never be more than about 30 chats for any user.
You can store the enabled conversations in an array that you use to show, and when you disable a conversation you can just add a hidden prop to it which you pass to the conversation and make it return null. This will make it not render anything but will not unmount it since you have not removed it from the array that handles the display of conversations.
example at: https://codesandbox.io/s/wispy-forest-59bqj
This is a bit hard to answer since you haven't posted the code.
But, theoretically, the best way to approach this problem is to transfer the data from your sidebar component and load it onto the right component on a per-user basis. You don't have to mount each "conversation component".
You can do this by with the boolean hidden property in your markup. React will render as usual and simply pass it along to the html, the browser will then simply not paint it.
const HideMe = ({ isHidden }) => (
<div hidden={isHidden}>
can you see me?
</div>
)
I made an example for you:
https://codesandbox.io/s/elastic-curie-t4ill?file=/src/App.js
reference: https://www.w3schools.com/tags/att_hidden.asp
I am creating a profile screen for user in my apps . I am using lightbox from React-Native-Navigation by wix to perform an edit profile . So , the user will click the touchableopacity and a lightbox will pop up and the user will enter the new information and save it . So, im wonder is it possible if i want to pass the textinput value from lightbox to the parent(profile.js) so that i can setstate in the profile.js ?
Yes this is possible. You will need to send the data as props to the parent. If you haven't done it before it might feel a bit tricky but you'll get there.
From the parent:
<LightboxComponent
userData={this.handleUserData(data)}
/>
handleUserData(data) {
/* Do something with the data here */
}
From the child:
To send the data you need to set an onChange event or similar on the input you want to capture, like this:
<input name="user-name" onChange={ (e) => this.props.userData(e.target.value) }
This will make the input data from the child get sent to the parent. Every change will trigger a re-render of the affected components.
If your app complains about not being able to setState correctly, then you need to bind this in the parents constructor like this:
this.handleUserData = this.handleUserData.bind(this);
I would also say pass the parent's function pointer to the child as props (as seen on the React site). Although some people opt for using an event emitter. I'm actually really curious about more developers' opinions on that.
Is derailing a thread on StackOverflow grounds for epic down voting?
I'm running into a weird case that only seems to happen upon first loading a component on a heavily based component page (loading 30+ components).
#Component{
selector: <parent-component>
template: `<child-component [myObject]=myObject>
}
export class ParentComponent {
private myObject:DTOValue;
constructor(service:MyService){
service.getDTOValue().subscribe((dtoValue:DTOValue) => {
this.myObject = dtoValue;
});
}
}
#Component{
selector: <child-component>
template: `<div></div>
}
export class ChildComponent {
#Input set myObject(value:DTOValue) => {//do something};
constructor(){
}
}
In this code, the Parent is going to get a value to a child as an input. This value comes from a request at a later time, so when the child is first initialized, the input could be undefined. When the value does get returned from the request and is set on the variable myObject, I'd expect that the child component would receive an input event being triggered. However, due to the timing, it seems like this is not always the case, especially when I first load a page that contains a lot of files being loaded.
In the case that the child component doesn't receive the input, if I click else where on my page, it seems to now trigger the change detection and will get the input value.
The 2 possible solutions I can think of that would require some large code changes so I want to make sure I choose the right now before implement them.
Change the input to be an Subject, so that I push the input value which should ensure that a correct event is triggered(this seems like overkill).
Use the dynamic loader to load the component when the request as return with the correct value (also seems like overkill).
UPDATE:
Adding a plnker: http://plnkr.co/edit/1bUelmPFjwPDjUBDC4vb, you can see in here that the title seems to never get its data bindings applied.
Any suggestions would be appreciated.
Thanks!
If you can identify where the problem is and appropriate lifecycle hook where you could solve it, you can let Angular know using ChangeDetectorRef.
constructor(private _ref: ChangeDetectorRef)
method_where_changes_are_overlooked() {
do_something();
// tell angular to force change detection
this._ref.markForCheck();
}
I had a similar issue, only with router - it needed to do redirect when/if API server goes offline. I solved it by marking routerOnActivate() for check...
When you trigger change detection this way a "branch" of a component tree is marked for change detection, from this component to the app root. You can watch this talk by Victor Savkin about this subject...
Apologize, the issue ended up being my interaction with jQuery. When I triggered an event for a component to be loaded, inside of the jQuery code, it wouldn't trigger the life cycle. The fix was after the code was loaded to then call for a change detection.
I've got an OAuth process that pops up a window, but when I log in, the redirect to the OAuth callback page happens within the popup rather than the parent window (window.opener). This might be a bit hacky, but I'd like a way for the popup window to tell the parent "we're authorized!"
This actually works:
OAuthCallback = React.createClass({
displayName: 'OAuthCallback',
render() {
window.opener.console.log('hello parent window');
return (
<div>
Hi, OAuth is process is done.
</div>
)
}
});
But I'm wondering if there's some way I can have the popup window tell the parent window to call a prop function, e.g. this.props.oauthSucceeded().
When you are unable to establish any parent-child or sibling relationship between the components, React recommends setting up an event system.
For communication between two components that don't have a
parent-child relationship, you can set up your own global event
system. Subscribe to events in componentDidMount(), unsubscribe in
componentWillUnmount(), and call setState() when you receive an event.
Flux pattern is one of the possible ways to arrange this.
see https://facebook.github.io/react/tips/communicate-between-components.html
Have a look at window.postMessage for cross window communication (https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)
Eelke's suggestion was spot on.
I used window.postMessage() in the child window, then window.close(), then added a window.addEventListener('message', function(){}) in the componentDidMount method of of main/master component.
Check out https://facebook.github.io/react/tips/dom-event-listeners.html for more information!
I had a unique situation where I had to work on an iframed react popup from an asp.net application. I had to provide a x button to close the popup by calling a closePopup method in the parent asp.net in addition to other ways to close it. I used window.parent. Below is how I used it.
if (window && window.parent) {
window.parent.closePopup();
}