JS / Angular / Places API - document.getElementById(key).value表单输入问题

时间:2016-11-26 02:25:49

标签: javascript angularjs forms google-maps-api-3 google-places-api

我正在使用Google Places API在用户搜索时自动将位置/目标填充到表单中。我有正确的表单自动填充,但是当我将表单提交到我的数据库时,该对象每次都是未定义的。当我在自动填充发生后尝试提交表单时,会出现问题。

奇怪的是,如果我手动将自动填充的相同信息复制并粘贴到相同的文本字段中,则会提交表单并将数据输入到我的数据库中,没有任何问题。

有关为何发生这种情况的任何想法?如果我自动将正确的值填充到表单中,那么当我转到控制器时,不应该将值绑定到我的ng模型吗?

HTML ========================

<div class="container-fluid">
    <div class="row">
        <div class="col-md-2">
            <h3>Markers</h3>
            <form ng-submit="addMarker(newMarker)">
                <div class="form-group">
                    <p>Add a new marker: </p>
                    <div class="form-group">
                        <input type="text" class="form-control" id="title" placeholder="Title" ng-model="newMarker.title">
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" id="address" placeholder="Address" ng-model="newMarker.address">
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" id="category" placeholder="Category" ng-model="newMarker.category">
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" id="url" placeholder="URL (optional)" ng-model="newMarker.url">
                    </div>
                    <div class="form-group">
                        <textarea type="textarea" class="form-control" id="description" placeholder="Message (optional)" ng-model="newMarker.description"></textarea>
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" id="list" placeholder="Add to a list (optional)" ng-model="newMarker.list">
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" id="latitude" placeholder="Latitude" disabled="true" ng-model="newMarker.latitude">
                    </div>
                    <div class="form-group">
                        <input type="text" class="form-control" id="longitude" placeholder="Longitude" disabled="true" ng-model="newMarker.longitude">
                    </div>
                    <input type="submit" class="btn btn-primary">
                </div>
            </form>
        </div>
        <div class="col-md-10">
            <input id="pac-input" class="controls" type="text" placeholder="Search Box">
            <div id="map"></div>
        </div>
    </div>
</div>

JS ==========================

// Get the HTML input element for search for the autocomplete search box
var input = document.getElementById('pac-input');
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);

// Create the autocomplete object.
var autocomplete = new google.maps.places.Autocomplete(input);

// Event Listener for a Places API search
google.maps.event.addListener(autocomplete, 'place_changed', function(){
    var infoWindow = new google.maps.InfoWindow({map: map});
    var place = autocomplete.getPlace();
    var contentString = '<p><b>'+place.name+'</b></p>'+
                        '<p>'+place.formatted_address+'</p>';
    var pos = {
            lat: place.geometry.location.lat(),
            lng: place.geometry.location.lng()
        };
    fillInForm(place);
    map.setCenter(pos);
    infoWindow.setPosition(pos);
    infoWindow.setContent(contentString);
    });
});

// Auto fill the form from the Places API search
var fillInForm = function(place) {
  // Get the place details from the autocomplete object.
    var lat = place.geometry.location.lat();
    var lng = place.geometry.location.lng();
    var markerForm = {
            title: place.name,
            address: place.formatted_address,
            coordinates: ""+lat+", "+lng+""
    };
    for (var key in markerForm) {
        document.getElementById(key).value = '';
        document.getElementById(key).disabled = false;
        var val = markerForm[key];
        document.getElementById(key).value = val;
    }
    $scope.markerForm = markerForm;
}

// CREATE NEW MARKER ===============================
$scope.addMarker = function() {
    markersFactory.addMarker($scope.newMarker, function(returnDataFromFactory){
        if(returnDataFromFactory.hasOwnProperty('errors')){
            $scope.newMarkerErrors = returnDataFromFactory.errors;
        } else {
            // console.log(returnDataFromFactory.data);
            $scope.newMarker = {};
        }
    })
}

编辑:添加了容器的其余部分。以前只提供表格div。添加了pac-input和map div。

1 个答案:

答案 0 :(得分:0)

当表单元素像这样更新时(通过document.getElementById函数直接进行DOM操作):

for (var key in markerForm) {
    document.getElementById(key).value = '';
    document.getElementById(key).disabled = false;
    var val = markerForm[key];
    document.getElementById(key).value = val;
}

Angular并不知道这些变化。

data binding Angular方式将用以下内容替换fillInForm函数:

var fillInForm = function (place) {
    $scope.$apply(function(){
       $scope.newMarker.title =  place.name;
       $scope.newMarker.address = place.formatted_address;
       $scope.newMarker.latitude = place.geometry.location.lat();
       $scope.newMarker.longitude = place.geometry.location.lng();
    });  
}
  自$apply事件被触发后,此处需要

place_changed   在Angular digest loop之外

演示:plunker