正确使用 ng-submit
Proper use of ng-submit
我有一个表单可以向 Google 的地理编码器和 returns lat/long 提交位置并更改地图。如果我在图标上使用 ng-click 它不起作用,除非我点击它两次。如果我在表单上使用 ng-submit,它会附加到 url 并且不执行任务。我觉得我快要完成这项工作了,但我不知道自己做错了什么。
下面是表格
<li>
<form action="" class="search-form" ng-submit="convertLatLonToAddress()">
<div class="form-group has-feedback">
<label for="search" class="sr-only">Search</label>
<input type="text" class="form-control" name="search" id="search" placeholder="Search for an address or place name">
<i class="fa fa-search form-control-indicator"></i>
</div>
</form>
</li>
这里是函数
$scope.convertLatLonToAddress = function(){
var address = $('#search').val();
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
// console.log(latitude + ' and ' + longitude);
$scope.center.lat = latitude;
$scope.center.lon = longitude;
}
});
};
感谢@PSL,它已修复!见下文:
<li>
<form class="search-form" ng-submit="convertLatLonToAddress(searchText)">
<div class="form-group has-feedback">
<label for="search" class="sr-only">Search</label>
<input type="text" class="form-control" name="search" id="search" placeholder="Search for an address or place name" ng-model="searchText">
<button style="visibility: hidden"></button>
<a ng-click="convertLatLonToAddress(searchText)">
<i class="fa fa-search form-control-indicator"></i>
</a>
</div>
</form>
</li>
和
$scope.convertLatLonToAddress = function(searchText){
// var address = $('#search').val();
var address = searchText;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
// console.log(latitude + ' and ' + longitude);
$scope.center.lat = latitude;
$scope.center.lon = longitude;
$scope.$apply();
}
});
};
您需要在 geocode
的异步调用中手动调用摘要循环,因为 geocode
在 angular 上下文中不会 运行。
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
// console.log(latitude + ' and ' + longitude);
$scope.center.lat = latitude;
$scope.center.lon = longitude;
$scope.$apply();
}
});
每次单击时,ng-click
都会触发摘要循环,因此上一个循环 运行 是非 angular 异步调用和更新的范围,angular 并不知道,当您再次单击它 运行 再次进入摘要循环并执行相同的操作,但此时将选择您之前设置的值,这就是为什么需要单击 2 次的原因。要执行 ng-submit
,您需要一个表单元素触发器,例如:一个 button
或 input type="submit"
,它会导致表单上发生提交行为。您还应该从表单中删除 action
除非您真的打算进行重定向。
除此之外,您还可以在文本框上使用 ng-model
并将值传递给您的函数,而不是直接从 DOM 获取值。
<input type="text" class="form-control" name="search" id="search" placeholder="Search for an address or place name" ng-model="searchText">
并通过 ng-click
将值作为 ng-click="convertLatLonToAddress(searchText)"
传递,并在您的函数中使用它。
为了避免在控制器中使用 scope.apply();
,您可以将 geoCoder
抽象为 angular 服务和 return 承诺(创建延迟对象)并使用它控制器中的服务。
myApp.service('geoCoderService', ['$q', function($q){
this.getCoordinates = function(address){
var defer = $q.defer();
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
return defer.resolve({latitude :latitude , longitude :longitude });
}
//faliure
defer.reject(status);
});
return defer.promise;
}
});
注入 geoCoderService
并使用以下方法获取数据:
geoCoderService.getCoordinates(address).then(function(coordinates){
//populate it
}).catch(function(errorStatus){ /*ooops Error*/ })
试试这个
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.convertLatLonToAddress = function() {
var address = $('#search').val();
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$scope.lat = results[0].geometry.location.lat();
$scope.lon = results[0].geometry.location.lng();
console.log($scope.lat + ' and ' + $scope.lon);
setTimeout(function(){$scope.$apply();},0)
}
});
};
});
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<li>
<div class="form-group has-feedback">
<label for="search" class="sr-only">Search</label>
<input type="text" class="form-control" name="search" id="search" placeholder="Search for an address or place name">
<i class="fa fa-search form-control-indicator"></i>
<button ng-click="convertLatLonToAddress()">Click</button>
<br>
Lat : <input type="text" ng-model="lat"><br>
Lon : <input type="text" ng-model="lon">
</div>
</li>
</div>
</body>
我有一个表单可以向 Google 的地理编码器和 returns lat/long 提交位置并更改地图。如果我在图标上使用 ng-click 它不起作用,除非我点击它两次。如果我在表单上使用 ng-submit,它会附加到 url 并且不执行任务。我觉得我快要完成这项工作了,但我不知道自己做错了什么。
下面是表格
<li>
<form action="" class="search-form" ng-submit="convertLatLonToAddress()">
<div class="form-group has-feedback">
<label for="search" class="sr-only">Search</label>
<input type="text" class="form-control" name="search" id="search" placeholder="Search for an address or place name">
<i class="fa fa-search form-control-indicator"></i>
</div>
</form>
</li>
这里是函数
$scope.convertLatLonToAddress = function(){
var address = $('#search').val();
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
// console.log(latitude + ' and ' + longitude);
$scope.center.lat = latitude;
$scope.center.lon = longitude;
}
});
};
感谢@PSL,它已修复!见下文:
<li>
<form class="search-form" ng-submit="convertLatLonToAddress(searchText)">
<div class="form-group has-feedback">
<label for="search" class="sr-only">Search</label>
<input type="text" class="form-control" name="search" id="search" placeholder="Search for an address or place name" ng-model="searchText">
<button style="visibility: hidden"></button>
<a ng-click="convertLatLonToAddress(searchText)">
<i class="fa fa-search form-control-indicator"></i>
</a>
</div>
</form>
</li>
和
$scope.convertLatLonToAddress = function(searchText){
// var address = $('#search').val();
var address = searchText;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
// console.log(latitude + ' and ' + longitude);
$scope.center.lat = latitude;
$scope.center.lon = longitude;
$scope.$apply();
}
});
};
您需要在 geocode
的异步调用中手动调用摘要循环,因为 geocode
在 angular 上下文中不会 运行。
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
// console.log(latitude + ' and ' + longitude);
$scope.center.lat = latitude;
$scope.center.lon = longitude;
$scope.$apply();
}
});
每次单击时,ng-click
都会触发摘要循环,因此上一个循环 运行 是非 angular 异步调用和更新的范围,angular 并不知道,当您再次单击它 运行 再次进入摘要循环并执行相同的操作,但此时将选择您之前设置的值,这就是为什么需要单击 2 次的原因。要执行 ng-submit
,您需要一个表单元素触发器,例如:一个 button
或 input type="submit"
,它会导致表单上发生提交行为。您还应该从表单中删除 action
除非您真的打算进行重定向。
除此之外,您还可以在文本框上使用 ng-model
并将值传递给您的函数,而不是直接从 DOM 获取值。
<input type="text" class="form-control" name="search" id="search" placeholder="Search for an address or place name" ng-model="searchText">
并通过 ng-click
将值作为 ng-click="convertLatLonToAddress(searchText)"
传递,并在您的函数中使用它。
为了避免在控制器中使用 scope.apply();
,您可以将 geoCoder
抽象为 angular 服务和 return 承诺(创建延迟对象)并使用它控制器中的服务。
myApp.service('geoCoderService', ['$q', function($q){
this.getCoordinates = function(address){
var defer = $q.defer();
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
return defer.resolve({latitude :latitude , longitude :longitude });
}
//faliure
defer.reject(status);
});
return defer.promise;
}
});
注入 geoCoderService
并使用以下方法获取数据:
geoCoderService.getCoordinates(address).then(function(coordinates){
//populate it
}).catch(function(errorStatus){ /*ooops Error*/ })
试试这个
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.convertLatLonToAddress = function() {
var address = $('#search').val();
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$scope.lat = results[0].geometry.location.lat();
$scope.lon = results[0].geometry.location.lng();
console.log($scope.lat + ' and ' + $scope.lon);
setTimeout(function(){$scope.$apply();},0)
}
});
};
});
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<li>
<div class="form-group has-feedback">
<label for="search" class="sr-only">Search</label>
<input type="text" class="form-control" name="search" id="search" placeholder="Search for an address or place name">
<i class="fa fa-search form-control-indicator"></i>
<button ng-click="convertLatLonToAddress()">Click</button>
<br>
Lat : <input type="text" ng-model="lat"><br>
Lon : <input type="text" ng-model="lon">
</div>
</li>
</div>
</body>