Search code examples
angularjsangular-directive

Two way binding with controller in directive with isolated scope


Im developing a directive, where when the user will click UPDATE, a field for EmployeeId will show up, and that employeeId field on the directive should be bound directly to the controller when changes. If i isolate the scope it doesn't change the controller employeeId, if i dont, than all directives gets toggled.

Plunker: https://plnkr.co/edit/aq06WnfniN51iR7ZtFLc?p=preview

code:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
    $scope.employeeId = 'Josh'
    $scope.employeePin = '1234'

    $scope.updateFields = function() {
        alert(1);
    }
});

app.directive('crudEmp', function($parse) {
    var html =  '<div class="form-inline">\
                    <input type="text" class="form-control"\
                        placeholder="Employe ID"\
                        ng-model="employeeId"\
                        required\
                        ng-show="isEditing"/>\
                    <input type="password" class="form-control"\
                        placeholder="Employe PIN"\
                        ng-model="employeePin"\
                        ng-show="user.AdminSecurity && isEditing"\
                        ng-required="user.AdminSecurity"\
                        disabled/>\
                    <div class="col-md-12 text-right noPadding pt10 operationButtons" id="opBtn">\
                        <div class="col-md-12 noPadding" ng-hide="isEditing">\
                            <button class="btn btn-info" ng-click="toggleEditing()">Edit</button>\
                        </div>\
                        <div class="col-md-12 text-right noPadding" ng-hide="!isEditing">\
                            <button class="btn btn-success mr80 updateBtn" ng-click="ctrl.onClick(); toggleEditing()" ng-disabled="ctrl.valid">Update</button>\
                            <button class="btn btn-warning" ng-click="toggleEditing()">Cancel</button>\
                        </div>\
                    </div>';

    return {
        restrict: 'E',
        template: html,
        replace: true,
        bindToController: {
            employeeId: '=',
            employeePin: '=',
            valid: '=',
            onClick: '&',
        },
//      scope: true,   // When i make the scope true, it doesnt change the EmployeeId defined in the controller
        link: function(scope, element, attr){
            scope.onClick = attr.onClick;

            scope.toggleEditing = function() {
                scope.isEditing = !scope.isEditing;
                if(scope.isEditing){
                    element.closest('form').find(':input:not(.operationButtons button)').attr('disabled', false);
                    var getAllInputs = element.closest('form').find(':input').filter(':visible:enabled');
                    if(getAllInputs[0]){
                        getAllInputs[0].focus();
                    }
                }else{
                    element.closest('form').find(':input:not(.operationButtons button)').attr('disabled', true);
                }
            };
        },
        controllerAs: 'ctrl',
        controller: function($scope) {
            var ctrl = this;

            ctrl.onClick = function() {
                $scope.$eval($scope.onClick);
            };
        },
    };
});

Solution

  • If I understand you currently it would be solved by changing:

        ...
                restrict: 'E',
                template: html,
                replace: true,
                bindToController: {
                    employeeId: '=',
                    employeePin: '=',
                    valid: '=',
                    onClick: '&',
                },
        //      scope: true,   // When i make the scope true, it doesnt change 
    

    To:

    ...
            restrict: 'E',
            template: html,
            replace: true,
            scope: {
                employeeId: '=',
                employeePin: '=',
                valid: '=',
                onClick: '&',
            },
        ...
    

    You can verify the behaviour in my plunker: https://plnkr.co/edit/Xia8BhlfFJ6mqgLjaoOp?p=preview