Binding directive from object to ng-repeat in AngularJS

Viewed 33

I'm using a directive with ng-repeat, which looks like this:

<new-tax-country  
    ng-repeat="newItem in data.company.extraTaxCountries track by $index" 
    ng-model="data.company.extraTaxCountries[$index]"> 
</new-tax-country>

I'm adding objects in the array according to the need, like this:

$scope.addTaxCountry = function() {
   $scope.data.company.extraTaxCountries.push({});
}

On every click of the button, I'm adding a new empty object into the array, and also a new directive is created.

I need to bind the directive to the empty object, so that when I fill the fields inside the directive, those exist also in the previously empty object.

My directive so far looks like this:

(function() {

    angular.module('account-form-client-de')
        .directive("newTaxCountry", function(Countries) {
            var options = {
                restrict: 'E',
                require: 'ngModel',
                replace: true,
                scope: {
                    
                },
                link: function(scope, element, attrs, controller, $parent) {
                        
                    
                },
                templateUrl: 'template/directive/new-tax-country.html'
            };

            return options;
        });
})();

And the html:

<div class="newtaxcountry">
    <label for="new_taxid">
        bla
    </label>
    <input name="new_taxid" ng-model="newTaxInnerScope.new_taxid">
</div>

How could I proceed so that every newItem in data.company.extraTaxCountries automatically inherits the properties of the newTaxInnerScope object that exists inside the directive?

2 Answers

You need to set up a bidirectional binding in order to read and write back from within the inner directive to your variables.

I created a fiddle https://jsfiddle.net/aemw7d29/1/

The main part is this:

angular.module('account-form-client-de')
    .directive("newTaxCountry", [function(Countries) {
        function link(scope, element, attrs, controller, $parent) {
            scope.ngModel.a = scope.ngModel.a ? scope.ngModel.a++ : 1;
        }
        
        var options = {
            restrict: 'E',
            require: 'ngModel',
            replace: true,
            scope: { ngModel : '=' },
            link: link,
            template: '<div class="newtaxcountry"><label for="new_taxid">bla</label><input name="new_taxid" ng-model="newTaxInnerScope.new_taxid">{{ngModel}}</div>'
        };

        return options;
    }]);

Though there is accepted answer, I'll leave it here...

First of all if you need simple input for directive -- never name it ng-model (also you dont need to require ngModel directive), just take any other name e.g. country here:

<new-tax-country
  ng-repeat="country in data.company.extraTaxCountries track by $index" 
  country="country">
</new-tax-country>


.directive("newTaxCountry", [function(Countries) {
    var options = {
        restrict: 'E',
        replace: true,
        scope: { country : '=' },
        template: '<div class="newtaxcountry"><label for="new_taxid">bla</label><input name="new_taxid" ng-model="country.new_taxid"></div>'
    };
    
    return options;
}]);

You may want to use ng-model if you want to put this directive into some form and specify validators on it (not on underlined input element), then you require ngModelCtrl and work with it instead of scope binding.

Related