Search code examples
angularjsangularjs-components

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

Solution

  • 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