Angularjs服务范围+绑定

时间:2014-06-27 20:33:25

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

我希望运行以下控制器,但我的范围有问题。

我有一个服务,它调用两个函数来检索元数据以填充范围变量。

问题是使用服务回调数据会干扰代码中发生的其他操作。我有一个标签的指令,一旦验证规则,它就会显示/隐藏span元素上的错误。这现在无法正常运行。我在没有异步函数的情况下运行代码,然后一切正常。

My Plunker code is here

并且所需行为的掠夺者在这里

Plunker working example without dynamic data loading

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

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

如何更新所有绑定以便正确同步和加载所有内容?

       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) {

    alert("here");

    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.Fields = 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;

                            //alert("called");

                            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 个答案:

没有答案