0

フォームの動的作成に問題があります。フォーム要素に対して設定されるディレクティブがあります。Jquery を使用して ID で要素を取得します。ただし、まだ DOM に追加されていないようです。

            <form class="form-horizontal">
            <div class="control-group" ng-repeat="field in viewModel.fields">
                <label class="control-label">{{field.label}}</label>
                <div class="controls" ng-switch="field.type">
                    <input ng-switch-when="text" type="text" id="{{field.label}}" ng-model="field.data" validator="viewModel.validator"  ruleSetName="personFirstNameRules"/>
                    <span ng-switch-when="text" validation-Message-For="{{field.label}}"></span>
                </div>
            </div>

            <button ng-click="testID()">Submit</button>
        </form>

テキストフィールドの ID 属性とスパン要素の validation-Message-For をハードコーディングした場合、問題はありません。未定義になっている領域は

    var errorElementController = angular.element(errorElement).controller('ngModel');
    var validatorsController = angular.element(errorElement).controller('validator');

完全なディレクティブはこちら

(function (angular, $) {

angular.module('directivesModule')
       .directive('validationMessageFor', [function () {
           return {
               link: function (scope, element, attributes) {
                   var errorElementId = attributes.validationMessageFor;
                   if (!errorElementId) {
                       return;
                   }
                   var areCustomErrorsWatched = false;

                   var watchRuleChange = function (validationInfo, rule) {
                        scope.$watch(function () {
                             return validationInfo.validator.ruleSetHasErrors(validationInfo.ruleSetName, rule.errorCode);
                        }, showErrorInfoIfNeeded);
                   };

                   var watchCustomErrors = function (validationInfo) {
                       if (!areCustomErrorsWatched && validationInfo && validationInfo.validator) {
                           areCustomErrorsWatched = true;
                           var validator = validationInfo.validator;
                           var rules = validator.validationRules[validationInfo.ruleSetName];
                           for (var i = 0; i < rules.length; i++) {
                               watchRuleChange(validationInfo, rules[i]);
                           }
                       }
                   };


                   //alert(errorElementId);

                   // get element for which we are showing error information by id
                   var errorElement = $("#" + errorElementId);

                   console.log(angular.element(errorElement));

                   var errorElementController = angular.element(errorElement).controller('ngModel');
                   var validatorsController = angular.element(errorElement).controller('validator');

                   console.log(errorElementController);
                   console.log(validatorsController);

                   var getValidationInfo = function () {
                       return validatorsController && validatorsController.validationInfoIsDefined() ? validatorsController.validationInfo : null;
                   };

                   var validationChanged = false;
                   var subscribeToValidationChanged = function () {
                       if (validatorsController.validationInfoIsDefined()) {
                           validatorsController.validationInfo.validator.watchValidationChanged(function () {
                               validationChanged = true;
                               showErrorInfoIfNeeded();
                           });

                           // setup a watch on rule errors if it's not already set
                           watchCustomErrors(validatorsController.validationInfo);
                       }
                   };

                   var getErrorMessage = function (value) {
                       var validationInfo = getValidationInfo();
                       if (!validationInfo) {
                           return '';
                       }

                       var errorMessage = "";
                       var errors = validationInfo.validator.errors[validationInfo.ruleSetName];
                       var rules = validationInfo.validator.validationRules[validationInfo.ruleSetName];

                       for (var errorCode in errors) {
                           if (errors[errorCode]) {
                               var errorCodeRule = _.findWhere(rules, { errorCode: errorCode });
                               if (errorCodeRule) {
                                   errorMessage += errorCodeRule.validate(value).errorMessage;
                                   break;
                               }
                           }
                       }

                       return errorMessage;
                   };

                   var showErrorInfoIfNeeded = function () {
                       var validationInfo = getValidationInfo();
                       if (!validationInfo) {
                           return;
                       }

                       var needsAttention = validatorsController.ruleSetHasErrors() && (errorElementController && errorElementController.$dirty || validationChanged);
                       if (needsAttention) {
                           // compose and show error message
                           var errorMessage = getErrorMessage(element.val());

                           // set and show error message
                           element.text(errorMessage);
                           element.show();
                       } else {
                           element.hide();
                       }
                   };

                   subscribeToValidationChanged();
                   if (errorElementController)
                   {
                     scope.$watch(function () { return errorElementController.$dirty; }, showErrorInfoIfNeeded);
                   }
                   scope.$watch(function () { return validatorsController.validationInfoIsDefined(); }, subscribeToValidationChanged());
               }
           };
       }]);})
   (angular, $);

コンソールのエラーは

  TypeError: Cannot read property 'validationInfoIsDefined' of undefined
at subscribeToValidationChanged (http://localhost/trax/app/Directives/validationMessage.js:50:52)
at link (http://localhost/trax/app/Directives/validationMessage.js:103:24)
at nodeLinkFn (https://code.angularjs.org/1.2.13/angular.js:6271:13)
at compositeLinkFn (https://code.angularjs.org/1.2.13/angular.js:5682:15)
at publicLinkFn (https://code.angularjs.org/1.2.13/angular.js:5587:30)
at boundTranscludeFn (https://code.angularjs.org/1.2.13/angular.js:5701:21)
at Object.controllersBoundTransclude [as transclude] (https://code.angularjs.org/1.2.13/angular.js:6292:18)
at https://code.angularjs.org/1.2.13/angular.js:20073:32
at Array.forEach (native)
at forEach (https://code.angularjs.org/1.2.13/angular.js:304:11) <span ng-switch-when="text" validation-message-for="{{field.label}}" class="ng-scope"> 
4

1 に答える 1