简体   繁体   中英

AngularJS: two way data binding not working in nested ng-repeat

I am new to AngularJS . I am using nested ng-repeat to generate multiple forms. And form data is json which is dynamic. So the problem is Data binding for TEXT , TEXTAREA and SELECT input is not working.

JSFiddle: http://jsfiddle.net/gTc5v/10/

HTML:

<div ng-controller="ctrl">
    <div ng-repeat="form in forms">
         <h2>{{form.name}}</h2>

         <div ng-repeat="field in form.form_fields">

         <div ng-If="showElement(field,'RADIO')">
         <div>   
         <h3>{{field.caption}}</h3>
         <span ng-repeat="option in field.optionValues">
         <input ng-model="field.answer" type="radio" value="{{option}}" >{{option}}
            <br/></input>
         </span>
         </div>
         </div>

         <div ng-If="showElement(field,'TEXT')">
         <input ng-model="field.answer" type="text" placeholder="{{field.caption}}" />
         </div>

         <div ng-If="showElement(field,'PARAGRAPH_TEXT')">
         <textarea ng-model="field.answer" placeholder="{{field.caption}}"></textarea>
         </div>

         <div ng-If="showElement(field,'LIST')">
         <div>
         <h3>{{field.caption}}</h3>
         <select ng-model="field.answer">
            <option ng-repeat="option in field.optionValues">{{option}}</option>
         </select>
         </div>
         </div>

         <div ng-If="showElement(field,'CHECKBOX')">
         <div>
         <h3>{{field.caption}}</h3>
         <span ng-repeat="option in field.optionValues">
             <input ng-checked="field.answers.indexOf(option) != -1" ng-click="toggleCheck(field.answers,option)" type="checkbox">{{option}}
             <br/></input>
         </span>
         </div>
         </div>
     </div>
     <br/>
     <div ng-repeat="field in form.form_fields">
     {{field.caption}} : {{field.answer}}{{field.answers}}
     </div>
     <br/>

 </div>

AangularJS:

angular.module('myApp', []).directive('ngIf', function () {
    return {
        link: function (scope, element, attrs) {
        if (scope.$eval(attrs.ngIf)) {
            // remove '<div ng-if...></div>'
            element.replaceWith(element.children());
        } else {
            element.replaceWith(' ');
        }
    }
};
});

function ctrl($scope) {

    $scope.fields = [{
        "caption": "Gender",
        "questionType": "RADIO",
        "optionValues": ["Male", "Female"],
        "fieldPriority": "INCLUDE"
     }, {
        "caption": "City",
        "questionType": "TEXT",
        "optionValues": "",
        "fieldPriority": "INCLUDE"
     }, {
        "caption": "Address",
        "questionType": "PARAGRAPH_TEXT",
        "optionValues": "",
        "fieldPriority": "INCLUDE"
     }, {
        "caption": "Nationality",
        "questionType": "LIST",
        "optionValues": ["Indian", "American"],
        "fieldPriority": "INCLUDE"
     }, {
        "caption": "Tea/Coffee",
        "questionType": "CHECKBOX",
        "optionValues": ["Tea", "Coffee"],
        "fieldPriority": "INCLUDE"
     }];

    angular.forEach($scope.fields, function(field) {
        if(field.questionType == 'CHECKBOX'){
           field.answers = [];
        } else{
           field.answer = "";
        }
    });

    $scope.forms = [{"name":"Form 1","form_fields" : angular.copy($scope.fields)},{"name":"Form 2","form_fields" : angular.copy($scope.fields)}];

    $scope.showElement = function (field, type) {
        return field.questionType == type;
    };

    $scope.toggleCheck = function (answer, option) {
        if (answer.indexOf(option) === -1) {
            answer.push(option);
        } else {
            answer.splice(answer.indexOf(option), 1);
        }
    };
}

thanks

Try to remove element.replaceWith below in your directive link function.

element.replaceWith(element.children());

You don't need to call replaceWith() in directive because directive has wrapped the template content and it will be included once compiled.

Here is a workable jsfiddle demo

Do you really need your own ng-If directive? Your example works fine if you use the built-in ng-if .

Note that in either case you need to write it as a lower-case ng-if in your HTML.

Update : jsfiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM