calling grandparent method from inside the grandchild component - javascript

i have 3 nested components
<GrandParent />
<Parent />
<Child />
i have a button in my Child component and on double click i would like to call a function in GrandParent component
<button #dblclick="this.$parent.callGrandParentFunction(model)"> call grandparent </button>
using this.$parent i can only access Parent methods ... is there any way to go one level higher and call a GrandParent method ?
there is a similar question on SO but it's about vue2
VueJS Grandchild component call function in Great grandparent component

Try to use provide/inject pattern :
GrandParent :
export default {
methods: {
someMethod(){
//
}
},
provide() {
// use function syntax so that we can access `this`
return {
someMethod: this.someMethod
}
}
}
in GrandChild component :
export default {
inject: ['someMethod'],
created() {
//run the method
this.someMethod()
}
}

Related

(Vue.js 3 Options API) How do I access a child method?

I need to access a child component's method using Vue.js 3 with Options API. There is an answer at How to access to a child method from the parent in vue.js, but it is for Vue.js 2 and Vue.js 3 but with Composition API.
I still tried this, all in the parent component:
<dropdown-list #update="updateChildComponents"></dropdown-list>
<child-component-1 ref="childComponent1Ref" :url="url"></child-component-1>
<child-component-2 ref="childComponent2Ref" :url="url"></child-component-2>
and
methods: {
updateChildComponents() {
this.$refs.childComponent1Ref.childComponentMethod();
this.$refs.childComponent2Ref.childComponentMethod();
}
}
This actually successfully accesses the method, but I think this may not be the right way.
Secondly, I use a prop in the child component that I update in the parent and use in the child component's method, which updates only after the second event. I think these two may be related.
Child component:
props: ['url'],
methods: {
childComponentMethod() {
console.log(this.url); // can access the value from the previous event
}
}
I appreciate any help.
For communication between the parent and the children you should trasfer the value with props. In case the value is changing in the parent you must add watch.
It called 1 way binding because the parent cant see the changes in the child component.
Parent -> child = use props.
Child -> parent = use emits and on event.
<script>
import { reactive,watch, computed,onMounted } from "vue";
export default {
components: {
},
props: { metadata: String },
emits: [""],
setup(props) {
onMounted(async () => {
//first initilize
if (props.metadata) {
state.metadataName = props.metadata;
}
});
//track after the changes in the parent
watch(
() => props.metadata,
async (metadata) => {
if (metadata) {
}
}
);
return {
};
},
};
</script>

Get calling component in React

How do you get access to the calling component in react?
function MyCallingComponent() {
return <MyReadingComponent/>
}
function MyReadingComponent() {
console.log(callingComponent.state)
}
You don't. The parent component can pass data and functions to the child via props, though. So for instance, if the parent needed a callback from the child in some circumstance:
function MyCallingComponent() {
function callback() {
// ...
}
return <MyReadingComponent callback={callback}/>;
}
function MyReadingComponent({callback}) {
// ...use `callback` where appropriate...
}
react uses unidirectional data flow, so if you need to access parent's state in your child component you need to pass it down as a prop.
class ParentComponent ...{
state={ foo : 'A' }
render(){
return <ChildComponent foo={this.state.foo}/>
}
}
as #t-j-crowder has said if you need to pass data from child to parent you may use callback method.

How do I reference a Svelte component's parent component?

Per the Svelte documentation on Props I am using props to pass a reference to the parent component to a child.
Props, short for 'properties', are the means by which you pass data down from a parent to a child component
That's exactly what I want to do. Here is a Svelte REPL with my code, that is also copied below:
My parent is App.html:
<div class='widget-container'>
<Widget foo bar="static" {baz}/>
</div>
<script>
import Widget from './Widget.html';
export default {
data: function(){
return {
baz: 'click me and check the console'
}
},
components: {
Widget
}
};
</script>
The child component is Widget.html:
<p>foo: {foo}</p>
<p>bar: {bar}</p>
<p>baz: {baz}</p>
<script>
export default {
oncreate: function(){
window.document.body.addEventListener('click', function(event){
console.log(`Clicked!, ${baz}`)
});
}
}
</script>
Thanks to the props, the HTML <p> elements can clearly reference the parent. However how can I reference the values in the parent component in the child component's JavaScript?
Inside lifecycle hooks and methods, access state with this.get():
<p>foo: {foo}</p>
<p>bar: {bar}</p>
<p>baz: {baz}</p>
<script>
export default {
oncreate: function(){
window.document.body.addEventListener('click', () => {
const { baz } = this.get();
console.log(`Clicked!, ${baz}`)
});
}
}l
</script>

Reactjs call componentWillMount of parent component

I have two components as below:
class Parent
{
componentWillMount () {
console.log('parent componentWillMount');
}
}
class Child extends Parent
{
componentWillMount () {
console.log('child componentWillMount');
}
}
But when the child component is loaded the componentWillMount method of the parent component is not loaded automatically. How do you call componentWillMount method of the parent component ?
Thanks
class Child extends Parent
{
componentWillMount () {
super.componentWillMount() ; //parent componentWillMount
console.log('child componentWillMount');
}
}
explain :
Child#componentWillMount overrides Parent#componentWillMount. So :
if you need only logic of Parent#componentWillMount without adding extra-logic, it is recommended to remove componentWillMount from Child .
If you need to call Parent#componentWillMount with appending some logic, retain Child#componentWillMount and call inside it super.componentWillMount();
You can call a parent's method in the follow manner:
class Child extends Perent {
componentWillMount () {
super.componentWillMount();
// Insert your child specific code here
}
}
But as Ben Nyrberg already mentioned in the comments it's not a good practice.
The good practice of reusing components code by following the React way is with components composition:
class Parent extends React.Component {
componentWillMount() {
// Reusable functionality here
}
render() {
return {this.props.children}
}
}
class Child extends React.Component {
componentWillMount() {
// Child specific functionality
}
render() {
return <div>Whatever you want</div>
}
}
class App extends React.Component {
render() {
return <Parent>
<Child />
</Parent>
}
}

Pass action to a component with the parent's context in Aurelia

How can you pass an action from a parent view/component to a child component and still maintain the context of the parent. The problem shown in the below plunkr shows that if the action is executed in the component it is in the context of the component and not the parent who passed the action. Basically the typical "that = this" issue.
Yes you can use eventAggregator to do this, but how would you without it. Would you have to pass the whole viewModel into the component?
http://plnkr.co/edit/n1xPUdR5nhXwwIivawBj?p=preview
// app.js
import { inject } from 'aurelia-framework';
import { MyService } from './my-service';
#inject(MyService)
export class App {
constructor(myService) {
this.myService = myService;
this.message = "Hello World!";
}
doThing() {
console.log('do a thing');
this.myService.foo();
}
}
<!--app.html-->
<template>
<require from="./my-component"></require>
<p>${message}</p>
<button click.delegate="doThing()">Do the thing - in app.html</button>
<my-component do.bind="doThing"></my-component>
</template>
// my-component.js
import { bindable } from 'aurelia-framework';
#bindable('do')
export class MyComponentCustomElement {
}
<!-- my-component.html -->
<template>
<button click.delegate="do()">Do the thing - in my-component</button>
</template>
// my-service.js
export class MyService {
foo() {
alert("pity da foo");
}
}
If you REALLY wanted to do this (there may be cleaner ways to go about it), you would need to get access to your parent's view-model from your child view-model and then, when calling the method in your child view's click binding, use .call() to change the scope/context of the do() method when it's called.
So in your child view-model, first gain access to your parent's view-model by adding the following bind method:
bind( bindingContext ) {
// bindingContext is your parent view-model
this.parent = bindingContext;
}
After you have access to your parent view-model you can update the click binding in your child view to be as follows:
<button click.delegate="do.call( parent )">Do the thing - in my-component</button>
This will call the do() method from the parent view-model's context.
You can use either .call( scope/context, list, of, args, ... ) or .apply( scope/context, [array of args]). For more info on the .call() method check out Mozilla's explanation

Categories

Resources