Wasimakram Mulla
Wasimakram Mulla

Reputation: 511

How to invoke a function in parent component from nested child component in Angular 1x

I have a parent component say purchaseComponent and a child component say supplierComponent. Supplier component works independently when I load it in a full view. Also I am successfully loading the supplierComponent in a modal inside purchaseComponent.

What I need is when I click addSupplier button which is in supplierComponent it should complete its current functionality and then call hide method from purchaseComponent.

supplierComponent

angular.module('TestApp').component('addsupplierComponent', {
    templateUrl: 'addsuppliercomponent/addsupplier.html',
    controller: AddsupplierController,
    controllerAs: 'addsupplierCtrl'
});

function AddsupplierController(){
    var vm = this;
    vm.addSupplier = addSupplier;
    function addSupplier(){
        console.log("supplier component")
    }
}

purchaseComponent

angular.module('TestApp').component('purchaseComponent', {
    templateUrl: 'purchasecomponent/purchase.html',
    controller: PurchaseController,
    controllerAs: 'purchaseCtrl'
});
function PurchaseController(ProductService, LogService){
    var vm = this;
    vm.hideModal = hideModal;
    function hideModal(){
        console.log("Hide Modal")
    }
}

purchase.html

<div class="modal-body">
        <div class="card-content table-responsive">
            <addsupplier-component></addsupplier-component>
        </div>
 </div>

Result I need: once I click addSupplier from purchaseComponent, output should be

Supplier component
Hide Modal

Upvotes: 3

Views: 7923

Answers (2)

georgeawg
georgeawg

Reputation: 48948

will [child]Component work independently without passing any parameter? coz I want this to work as an independent component too

To have the child component able to function independently, make the expression & binding optional with &? and check before invoking:

Child Component

app.component('childComponent', {
    templateUrl: 'component/child.html',
    controller: ChildController,
    controllerAs: 'childCtrl',
    bindings: {
        onDone: '&?'
    }
});

function ChildController(){
    var vm = this;
    vm.done = function done(){
        console.log("child function")
        vm.onDone && vm.onDone();
    }
}

Parent Component

app.component('parentComponent', {
    templateUrl: 'component/parent.html',
    controller: ParentController,
    controllerAs: 'parentCtrl'
});
function ParentController(ProductService, LogService){
    var vm = this;
    vm.hideModal = hideModal;
    function hideModal(){
        console.log("Hide Modal")
    }
}

parent.html

<div class="modal-body">
    <div class="card-content table-responsive">
        <child-component on-done="parentCtrl.hideModal()">
        </child-component>
    </div>
</div>

By using optional expression &? binding, the child component can operate independently:

<child-component></child-component>

From the Docs:

All 4 kinds of bindings (@, =, <, and &) can be made optional by adding ? to the expression. The marker must come after the mode and before the attribute name. This is useful to refine the interface directives provide.

— AngularJS Comprehensive Directive API Reference - scope

Upvotes: 6

cstuncsik
cstuncsik

Reputation: 2786

You have to pass the hide function in the component bindings

Check the docs here

addsupplierComponent

angular.module('TestApp').component('addsupplierComponent', {
    templateUrl: 'addsuppliercomponent/addsupplier.html',
    controller: AddsupplierController,
    controllerAs: 'addsupplierCtrl',
    bindings: {
        hideModal: '&'
    }
});

function AddsupplierController(){
   var vm = this;
   vm.addSupplier = addSupplier;
   function addSupplier(){
      vm.hideModal()
  }
}

purchase.html

<div class="modal-body">
    <div class="card-content table-responsive">
        <addsupplier-component hide-modal="purchaseCtrl.hideModal()"></addsupplier-component>
    </div>
</div>

Upvotes: 1

Related Questions