javascript - Angularjs Service Scope + Bindings -
i looking run following controller im having trouble scope.
i have service calls 2 functions retrieve meta data populate scope variables.
the issue using service call data interferes other actions happening in code. have directive on tag shows/hides error on span element once rule validated. not functioning correctly. run code without asynchronous functions works correctly.
and plunker of desired behaviour 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>
how bindings update sync , loaded correctly?
angular.module('dataapp', ['servicesmodule', 'directivesmodule']) .controller('datactrl', ['$scope', 'processservice', 'validationrulefactory', 'validator', function($scope, validationrulefactory, validator, processservice) { $scope.viewmodel = {}; var formfields = {}; // 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 @ least %s characters', maxlength: 'value length must less %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!'); } }; } ]);
the validation message directive here
(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]; (var = 0; < rules.length; i++) { watchrulechange(validationinfo, rules[i]); } } }; // element showing error information 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 watch on rule errors if it's not 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]; (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 , show error message var errormessage = geterrormessage(element.val()); // set , 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, $);
Comments
Post a Comment