AngularJS在google places指令中进行表单验证

时间:2015-10-26 19:13:11

标签: angularjs forms validation google-places-api directive

我有一个输入字段,由以下指令创建:

.directive('googlePlaces', function(){
        return {
            restrict:'E',
            replace:true,
            scope: {location:'='},
            template: function (elem, attrs) { 
                return '<div><div class="form-group" ng-class="{ \'has-error\' : '+attrs.form+'.google_places_ac.$invalid }"><label>Address*</label><input id="google_places_ac" required name="google_places_ac" type="text" class="form-control" placeholder="Address" /><p class="help-block" ng-message="required" ng-show="'+attrs.form+'.google_places_ac.$invalid">Message</p></div></div>'
            },
            link: function($scope, elm, attrs){
                var autocomplete = new google.maps.places.Autocomplete($("#google_places_ac")[0], {});
                google.maps.event.addListener(autocomplete, 'place_changed', function() {
                    var place = autocomplete.getPlace();
                    $scope.location = place.name + ',' + place.geometry.location.lat() + ',' + place.geometry.location.lng() + "," + place.formatted_address;
                    $scope.$apply();
                });
            }
        }
    })

我一直在努力为此字段添加必要的验证,但它不起作用。我对HTML表单中的其他输入字段执行相同的操作,并且工作正常。

这是相关的HTML:

<form name="registrationForm" ng-submit="register()" novalidate>
...
<div class="col-xs-12">
            <google-places location=location form="registrationForm"></google-places>
</div>
...

我尝试过很多不同的事情,scope: {location:'=', form:'='}$compile,只是直接添加名称registrationForm,或只是form。它都不起作用。

如果有人能帮助我,我真的很感激:)

1 个答案:

答案 0 :(得分:1)

你可以通过多种方式做到这一点。这里有几个。

1)从googlePlaces指令中隔离消息的验证和显示,访问表单等,并将其控制权交给消费者,因为它确实是消费者的关注点。他们可以完全控制如何显示,显示什么以及显示位置。这将避免对指令负责提供场所选择的任何更多责任。您的指令需要ng-model并指定必需属性。

粗略的实现就是这样的。

.directive('googlePlaces', function() {
  return {
    require:'ngModel',
    restrict: 'E',
    replace: true,
    scope: {
      location: '=ngModel'
    },
    template: function(elem, attrs) {
      return '<div><div class="form-group"><label>Address*</label><input id="google_places_ac" required name="google_places_ac" type="text" ng-model="locSearch" class="form-control" placeholder="Address" /></div><button type="button" ng-click="clear()">clear</button></div>'
    },
    link: function($scope, elm, attrs, ctrl) {
      var autocomplete = new google.maps.places.Autocomplete($("#google_places_ac")[0], {});
      google.maps.event.addListener(autocomplete, 'place_changed', function() {
        var place = autocomplete.getPlace();
        $scope.location = place.name + ',' + place.geometry.location.lat() + ',' + place.geometry.location.lng() + "," + place.formatted_address;
        $scope.$apply();
      });

      $scope.clear = function() {
        $scope.location = null;
      }
    }
  }
});

 <google-places name="location" ng-model=location required 
               ng-class="{ 'has-error' : registrationForm.location.$invalid }">
 </google-places>
 <span class="help-block" 
       ng-show="registrationForm.location.$invalid">Please specify location</span>

angular.module('app', []).directive('googlePlaces', function() {
  return {
    require:'ngModel',
    restrict: 'E',
    replace: true,
    scope: {
      location: '=ngModel'
    },
    template: function(elem, attrs) {
      return '<div><div class="form-group"><label>Address*</label><input id="google_places_ac" required name="google_places_ac" type="text" ng-model="location" class="form-control" placeholder="Address" /></div><button type="button" ng-click="clear()">clear</button></div>'
    },
    link: function($scope, elm, attrs, ctrl) {
      var autocomplete = new google.maps.places.Autocomplete($("#google_places_ac")[0], {});
      google.maps.event.addListener(autocomplete, 'place_changed', function() {
        var place = autocomplete.getPlace();
        $scope.location = place.name + ',' + place.geometry.location.lat() + ',' + place.geometry.location.lng() + "," + place.formatted_address;
        $scope.$apply();
      });

      $scope.clear = function() {
        $scope.location = null;
      }
    }
  }
});
.has-error input {
  border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<div ng-app="app">
  <form name="registrationForm" ng-submit="register()" novalidate>
    <div class="col-xs-12">
    
      <google-places name="location" ng-model=location required ng-class="{ 'has-error' : registrationForm.location.$invalid }"></google-places>
      <span class="help-block" ng-show="registrationForm.location.$invalid">Please specify location</span>
    </div>
  </form>
</div>

2)您可以双向将表单对象绑定到指令,并从那里控制验证和显示消息。您需要在输入上放置ng-model,以便验证正确启动。

.directive('googlePlaces', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      location: '=',
      form:'='
    },
    template: function(elem, attrs) {
      return '<div><div class="form-group" ng-class="{ \'has-error\' :form.google_places_ac.$invalid }"><label>Address*</label><input ng-model="selectedLocation" id="google_places_ac" required name="google_places_ac" type="text" class="form-control" placeholder="Address" /><p class="help-block" ng-message="required" ng-show="form.google_places_ac.$invalid">Message</p></div></div>'
    },
    link: function($scope, elm, attrs) {

      var autocomplete = new google.maps.places.Autocomplete($("#google_places_ac")[0], {});
      google.maps.event.addListener(autocomplete, 'place_changed', function() {

        var place = autocomplete.getPlace();
        $scope.location = place.name + ',' + place.geometry.location.lat() + ',' + place.geometry.location.lng() + "," + place.formatted_address;
        $scope.$apply();
      });
    }
  }
});

angular.module('app', []).directive('googlePlaces', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      location: '=',
      form: '='
    },
    template: function(elem, attrs) {
      return '<div><div class="form-group" ng-class="{ \'has-error\' :form.google_places_ac.$invalid }"><label>Address*</label><input ng-model="location" id="google_places_ac" required name="google_places_ac" type="text" class="form-control" placeholder="Address" /><p class="help-block" ng-message="required" ng-show="form.google_places_ac.$invalid">Message</p></div></div>'
    },
    link: function($scope, elm, attrs) {

      var autocomplete = new google.maps.places.Autocomplete($("#google_places_ac")[0], {});
      google.maps.event.addListener(autocomplete, 'place_changed', function() {

        var place = autocomplete.getPlace();
        $scope.location = place.name + ',' + place.geometry.location.lat() + ',' + place.geometry.location.lng() + "," + place.formatted_address;
        $scope.$apply();
      });
    }
  }
})
.has-error input {
  border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<div ng-app="app">
  <form name="registrationForm" ng-submit="register()" novalidate>
    <div class="col-xs-12">
      <google-places location=location form="registrationForm"></google-places>
    </div>
  </form>
</div>