Angularjs指令范围问题

时间:2014-07-01 18:13:23

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

我在使用指令时遇到问题。我的模型使用http调用加载的数据进行更新。如果没有调用该服务,该指令就可以正常工作。

我有一个名为validationmessagefor的指令,它会在字段被标记为有错误时进行侦听。如果有错误,则显示错误消息。

附带Plnkr

的掠夺者

在使用服务加载数据时,如何让指令响应或正确加载模型?

angular.module('dataApp', ['servicesModule', 'directivesModule'])
.controller('dataCtrl', ['$scope', 'ProcessService', 'ValidationRuleFactory', 'Validator',
function($scope, ValidationRuleFactory, Validator, ProcessService) {

  $scope.viewModel = {};
  var FormFields = {};

  // we would get this from the meta api

  ProcessService.getProcessMetaData().then(function(data) {

    FormFields = {
      Name: "Course",
      Fields: [{
        type: "text",
        Name: "name",
        label: "Name",
        data: "",
        required: true,
        ruleSet: "personFirstNameRules"
      }, {
        type: "text",
        Name: "description",
        label: "Description",
        data: "",
        required: true,
        ruleSet: "personEmailRules"
      }]
    };


    $scope.viewModel = FormFields;


    ProcessService.getProcessRuleData().then(function(data) {

      var genericErrorMessages = {
        required: 'Required',
        minlength: 'value length must be at least %s characters',
        maxlength: 'value length must be less than %s characters'
      };
      var rules = new ValidationRuleFactory(genericErrorMessages);

      $scope.viewModel.validationRules = {
        personFirstNameRules: [rules.isRequired(), rules.minLength(3)],
        personEmailRules: [rules.isRequired(), rules.minLength(3), rules.maxLength(7)]
      };



      $scope.viewModel.validator = new Validator($scope.viewModel.validationRules);

    });

  });

  var getRuleSetValuesMap = function() {
    return {
      personFirstNameRules: $scope.viewModel.Fields[0].data,
      personEmailRules: $scope.viewModel.Fields[1].data
    };
  };

  $scope.save = function() {
    $scope.viewModel.validator.validateAllRules(getRuleSetValuesMap());
    if ($scope.viewModel.validator.hasErrors()) {
      $scope.viewModel.validator.triggerValidationChanged();
      return;
    } else {
      alert('person saved in!');
    }
  };

}
  ]);

显示自定义错误消息的指令

(function(angular, $) {

angular.module('directivesModule')
        .directive('validationMessageFor', [function() {
                return {
                    restrict: 'A',
                    scope: {eID: '@val'},
                    link: function(scope, element, attributes) {

                        //var errorElementId = attributes.validationMessageFor;

                        attributes.$observe('validationMessageFor', function(value) {

                            errorElementId = value;


                            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]);
                                    }
                                }
                            };

                            // get element for which we are showing error information by id
                            var errorElement = $("#" + errorElementId);
                            var errorElementController = angular.element(errorElement).controller('ngModel');
                            var validatorsController = angular.element(errorElement).controller('validator');

                            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, $);

0 个答案:

没有答案