Angular2 Destroy Current Component Completely - javascript

I tried searching google and stackoverflow but could not find an answer. So my question is simple "How can i remove current component in angular 2, 4"
example:
<div (click)="remove($event)">Remove Current Component</div>
remove($event) {
// this.destroy() ????
}
Basically what i want is ComponentRef see this answer ngOnDestroy() which calls this.cmpRef.destroy() :
ngOnDestroy() {
if(this.cmpRef) {
this.cmpRef.destroy();
}
}
But he is getting the ComponentRef due to dynamically creating the component.

You can use a *ngIf="myBoolean" directive on the component element in the parent template. When myBoolean becomes false, the component will be destroyed.
No more component or DOM element present. (and ngOnDestroy event raised)
If myBoolean becomes true again, a new component will be instantiated.
A new one will appear in DOM (and ngOnInit event raised)
Your click event can emit an event (binded in the parent with the (myEventEmitter) syntax, and a method in the parent component can then just set the boolean to false.
Demonstration on this Plunker. If it doesn't suit your need, consider editing your question to provide more specific details, including a Minimal Complete Verifiable example

Related

Should you hide modals or remove them from the DOM in React?

I'm writing a React application with a lot of modals (but only one ever active at a time with no nested modals), and I'm unsure of which of these two solutions is preferable when it comes to handling showing and hiding these modals:
Have a state boolean variable in the parent component that determines whether or not the modal should be shown. If this boolean variable is false, don't render the component. If it's true, render it. Allow the modal to influence this event via a passed in props callback it can leverage. Example snippets:
{ this.state.prompt === "makePW" ?
<MakePassword closeModal={this.closePWModal} /> :
null
}
Now, within the component, it is always visible and does not control its lifecycle. If it is being rendered then it is visible.
Just always show the component in the parent component, like so:
<MakePassword />
Then within the component itself handle its entire lifecycle. That is, the component will have a boolean state variable for its visibility. Some snippets for this approach:
<Modal open={this.state.open} onClose={this.closeModal}>
<Modal.Header>Header</Modal.Header>
<Modal.Content>Body</Modal.Content>
</Modal>
There are also hybrid approaches, and other solutions as well I'm sure.
Regardless, I suppose the essence of my question is wondering about the preferable solution for showing and hiding modals: is it to always render them and just toggle their visibility, or to actually toggle between adding and removing them from the DOM? And, should the modal itself generally control its lifecycle or should the parent?
i prefer 1st one but if you want to use the second , i would extend the makepassword component from PureComponent to optimize your component.
Instead of writing shouldComponentUpdate() by hand, you can inherit from React.PureComponent. It is equivalent to implementing shouldComponentUpdate() with a shallow comparison of current and previous props and state. - source react docs
class MakePassword extends React.PureComponent{
...
}
I think it depends on your application.
For example, React-Bootstrap modals stay in the DOM and that allows for nice in/out animations.

Polymer 2.0 access a parent component from child component

I have a nested component, what is the Polymer way to travel up the DOM or component tree in this case.
<parent-component>
<some-component>
<component-i-am-starting-from></<component-i-am-starting-from>
</some-component>
<some-other-component>
</some-other-component>
</parent-component>
I'd like to be at a deep nested component and reference any of the parent components and their models or trigger an event inside one of them. Bonus if I can access sibling components, etc.
Traveling down was easy enough with
this.$.idOfChildComponent.event()
I have tried dispatchEvent, domHost, shadowRoot, can't seem to get any further up the component tree then the direct parent or get an error back that something is undefined, is not a function, etc.
Is there a way like React to pass a reference down as a property. The docs do not seem to be helpful nor scouring the internet.
Thanks!
update
So I am not sure if this is the correct way but it works ok calling a parent function from a child function.
<parent-component id="parentComponent">
<some-component>
<component-i-am-starting-from></<component-i-am-starting-from>
</some-component>
<some-other-component>
</some-other-component>
</parent-component>
componentIAmStartingFromFunc(){
document.getElementById('parentElement').parentElementFunc()
}
However does not seem to work for siblings?
** Update **
I essentially did the same the to call the sibling event by calling the parent from one of its children, and then sent out a trigger to the sibling which is also a child component.
Calling a parent function from child ;
child-component.html (polymer 2.x)
this.dispatchEvent(new CustomEvent('upway-func', {detail: {op:"Optionally I can send some data"}}));
child-component.html (polymer 1.x)
this.fire('upway-func', {detail: {op:"Optionally I can send some data"}});
parent-component.html
...
<child-component on-upway-func='_someFunction'></child-component>
...
_someFunction(d){
console.log(d.detail.op); // "Optionally I can send some data"
}
Here this link for more detail
Have you tried using this.parentElement?
Ask yourself: if I were a span in a div, how would I get to the div?
If you want to find a particular element in the ancestor chain by selector, you can use .closest() in good browsers or https://github.com/jonathantneal/closest
The message system mentioned in another answer can work but doesn't help you with positional relationship traversing which I assume your question was requiring. Passing ids and/or objects down can be used with messages in some cases.

Vue.js eventBus doesn't emit property after page refresh

I want to pass property from one component to other, they are siblings, after a page refresh. I want to do this on the page load.
I am using eventBus to do it:
EventBus.$emit('generatedSum', this.sum);
Receiving it in the sibling component with:
EventBus.$on('generatedSum', (sum) => {
this.correct = sum;
});
and I am puting both in the lifecycle hook:
created(){}
The problem is that after code is compiled after a saved change, I get the property emited to the sibling component, but when I manualy refresh the page the property is not visible in the sibling component.
I think when the page refreshes the Vue components mount one after another. Since both are siblings, when the first component trigger the event the second component may not be available to listen to the triggered event. Because the second component is mounted after the first component.
As a work around try
mounted() rather than using created() life cycle event.
More on life cycle events can be found here.
https://v2.vuejs.org/v2/guide/instance.html#Lifecycle-Diagram

How to detect when DOM is ready after *ngIf condition is set to true

I have an Angular 2 (Ionic 2) application where I hide some elements using an *ngIf if the network is offline, and show another button, "retry".
When I click the retry button, if the network is back I then want to reshow the elements hidden by the *ngIf. Also I then need to reference some of them via #ViewChild (e.g. an Ionic 2 slider to get it's current index). My problem is that these elements are not all defined when I try to get a reference to them in the same function call that sets my property bound to the *ngIf back to true.
I have tried calling from within a setTimeout but this does not seem to be very safe - some DOM elements are back but not all.
Is there a way to know then the DOM is ready with all the elements that were hidden by the *ngIf, or do I need to find some other way of doing this (not using the *ngIf, so elements are not actually removed).
Thanks in advance for any suggestions!
You should be able to do what you want by looking at the onStable event emitted via the NgZone:
In the component template:
<button (click)="showFoo = !showFoo">toggle</button>
<div *ngIf="showFoo" #foo >foo</div>
In your component class
#ViewChild('foo') foo: ElementRef;
showFoo = false;
constructor(private zone: NgZone) {
zone.onStable.subscribe(() => {
console.log(this.foo);
// this will log either undefined or an ElementRef as you toggle
});
}
Here's a plunk showing it working: https://plnkr.co/edit/jKSaEI0XUcJQehZnJTxB
I think you are looking to understand this,
I think the ngAfterViewInit() would help you with this,
ngAfterViewInit() Respond after Angular initializes the component's
views and child views.
Called once after the first ngAfterContentChecked().
A component-only hook.

How to call method of child component from parent in EmberJS

I’ve hit an interesting issue that doesn’t fit with Ember’s data down, actions up principle.
I have a code editor component (code-editor) sat inside a parent component (request-editor). There's a method on the editor component to insert a string at the current cursor position. The parent component includes some buttons to insert things into the editor (e.g. the current date).
I think I'm right in separating the buttons from the editor because the editor is used elsewhere without these buttons.
It obviously doesn't make sense to use a bound variable for this use-case because it's not really data, it's wanting to perform an action. I.e. {{code-editor insertText=insertText}} makes no sense.
How is it possible to effectively call codeEditorChildComponent.insert() from the parent component? I appreciate it will probably involve coupling them together but they have to be coupled for it to work anyway. The parent component is composed of the child components already.
All communications should be done using actions.
I think below is a good way. And you have code_editor property in request-editor component then could send action to code-editor component.
request-editor.hbs
{{code-editor owner=this}}
request-editor.js
actions:{
setChild(child){
this.set('code_editor', child);
}
}
code-editor.js
didInsertElement(){
this._super(...arguments);
this.get('owner').send('setChild', this);
}

Categories