1

Hier ist mein Problemelement.val() vorherigen Wert zurück

Ich versuche, eine Schaltfläche zu erstellen, die eine Richtlinie Funktion aufruft, die dann den Google-Ort aktiviert ‚place_changed‘ Ereignis, das die Richtlinie zugeordnet ist. Wenn die Funktion getPlace() kein Ergebnis z. var result = scope.gPlace.getPlace(); Dann möchte ich eine Ortsvorhersage erzwingen, indem ich Folgendes tue.

if(result === undefined) { 
    result = { name: element.val() } 
} 

aber das Problem ist, dass dieser Code funktioniert, wenn die Seite zum ersten Mal wird aber nachfolgende Versuche weisen Sie die result var geladen wird, um zum vorherigen Text, der eingegeben wurde. z.B. Geben Sie „Adelaide“ und klicken Sie auf die Schaltfläche gleich erfolgreichen Prozess aber jetzt Melbourne ein und klicken Sie auf die Schaltfläche wird immer noch gleich „Adelaide“

'use strict'; 
 
angular.module("ngAutocomplete", []) 
 
    .directive('ngAutocomplete', function() { 
 
    return { 
 
     require: 'ngModel', 
 
     scope: { 
 
     ngModel: '=', 
 
     options: '=?', 
 
     details: '=?', 
 
     setFn: '&' 
 
     }, 
 

 
     link: function(scope, element, attrs, controller) { 
 

 
     //options for autocomplete 
 
     var opts 
 
     var watchEnter = false 
 
     //convert options provided to opts 
 
     var initOpts = function() { 
 

 
      opts = {} 
 
      if (scope.options) { 
 

 
      if (scope.options.watchEnter !== true) { 
 
       watchEnter = false 
 
      } else { 
 
       watchEnter = true 
 
      } 
 

 
      if (scope.options.types) { 
 
       opts.types = [] 
 
       opts.types.push(scope.options.types) 
 
       scope.gPlace.setTypes(opts.types) 
 
      } else { 
 
       scope.gPlace.setTypes([]) 
 
      } 
 

 
      if (scope.options.bounds) { 
 
       opts.bounds = scope.options.bounds 
 
       scope.gPlace.setBounds(opts.bounds) 
 
      } else { 
 
       scope.gPlace.setBounds(null) 
 
      } 
 

 
      if (scope.options.country) { 
 
       opts.componentRestrictions = { 
 
       country: scope.options.country 
 
       } 
 
       scope.gPlace.setComponentRestrictions(opts.componentRestrictions) 
 
      } else { 
 
       scope.gPlace.setComponentRestrictions(null) 
 
      } 
 
      } 
 
     } 
 

 
     if (scope.gPlace == undefined) { 
 
      scope.gPlace = new google.maps.places.Autocomplete(element[0], {}); 
 
     } 
 

 
     google.maps.event.addListener(scope.gPlace, 'place_changed', function() { 
 

 
      var result = scope.gPlace.getPlace(); 
 

 
      //hack to make sure we have an object to pass to ensure we can get results from the called function activateGetPlace 
 
      if(result === undefined) { 
 
      result = { name: element.val() } 
 
      } 
 

 
      console.log("the result", result); 
 

 
      if (result !== undefined) { 
 

 
      if (result.address_components !== undefined) { 
 

 
       scope.$apply(function() { 
 
       scope.details = result; 
 
       controller.$setViewValue(element.val()); 
 
       }); 
 
      } 
 
      else { 
 
       if (watchEnter) { 
 
       getPlace(result) 
 
       } 
 
      } 
 
      } 
 
     }) 
 

 
     //function to get retrieve the autocompletes first result using the AutocompleteService 
 
     var getPlace = function(result) { 
 
      var autocompleteService = new google.maps.places.AutocompleteService(); 
 
      if (result.name.length > 0){ 
 
      autocompleteService.getPlacePredictions(
 
       { 
 
       input: result.name, 
 
       offset: result.name.length, 
 
       types: opts.types, 
 
      \t \t componentRestrictions: opts.componentRestrictions 
 
       }, 
 
       function listentoresult(list, status) { 
 
       if(list == null || list.length == 0) { 
 

 
        scope.$apply(function() { 
 
        scope.details = null; 
 
        }); 
 

 
       } else { 
 
        var placesService = new google.maps.places.PlacesService(element[0]); 
 
        placesService.getDetails(
 
        {'reference': list[0].reference}, 
 
        function detailsresult(detailsResult, placesServiceStatus) { 
 

 
         if (placesServiceStatus == google.maps.GeocoderStatus.OK) { 
 
         scope.$apply(function() { 
 

 
          controller.$setViewValue(detailsResult.formatted_address); 
 
          element.val(detailsResult.formatted_address); 
 

 
          scope.details = detailsResult; 
 

 
          //on focusout the value reverts, need to set it again. 
 
          var watchFocusOut = element.on('focusout', function(event) { 
 
          element.val(detailsResult.formatted_address); 
 
          element.unbind('focusout') 
 
          }) 
 

 
         }); 
 
         } 
 
        } 
 
       ); 
 
       } 
 
       }); 
 
      } 
 
     } 
 

 
     controller.$render = function() { 
 
      var location = controller.$viewValue; 
 
      element.val(location); 
 
     }; 
 

 
     //watch options provided to directive 
 
     scope.watchOptions = function() { 
 
      return scope.options 
 
     }; 
 

 
     scope.$watch(scope.watchOptions, function() { 
 
      initOpts() 
 
     }, true); 
 

 
     scope.activateGetPlace = function() { 
 
      google.maps.event.trigger(scope.gPlace, 'place_changed'); 
 
     } 
 

 
     scope.setFn({theDirFn: scope.activateGetPlace}); 
 

 
     } 
 
    }; 
 
    }); 
 
    
 
    var mechanicsearch = angular.module('mechanicsearch', ['ngRoute','ngResource','ngAutocomplete']), 
 
    radiusOptions = []; 
 

 
mechanicsearch.run(function($rootScope) { 
 
    $rootScope.$on('handleActiveJobsPanel', function(event, args) { 
 
     $rootScope.$broadcast('activateJobsPanel', args); 
 
    }); 
 
    $rootScope.$on('handleActiveFinalise', function(event, args) { 
 
     $rootScope.$broadcast('activateFinalisePanel', args); 
 
    }); 
 
    $rootScope.$on('handleActiveSearch', function(event, args) { 
 
     $rootScope.$broadcast('activateSearchPanel', args); 
 
    }); 
 
}); 
 

 
mechanicsearch.filter('htmlToPlaintext', function() { 
 
    return function(text) { 
 
    return text ? String(text).replace(/<[^>]+>/gm, '') : ''; 
 
    }; 
 
}); 
 

 
// mechFactory service 
 
mechanicsearch.factory('mechFactory', function($resource,$window) { 
 
    var mechanics = []; 
 
    var jobs = []; 
 

 
    var addMechanic = function(mechanic){ 
 
     mechanics.push(mechanic); 
 
    }; 
 

 
    var getAllMechanics = function(){ 
 
     return mechanics; 
 
    }; 
 

 
    var removeAllMechanics = function() { 
 
     mechanics = []; 
 
    } 
 

 
    var addJob = function(job) { 
 
     jobs.push(job); 
 
    } 
 

 
    var getAllJobs = function() { 
 
     return jobs; 
 
    } 
 

 
    var removeAllJobs = function() { 
 
     jobs = []; 
 
    } 
 

 
    return { 
 
     getMechanics: function(location,radius) { 
 
     return $resource('/ajax/api.cfm?api=mechanic&function=getMechanicByLocation&lat=:lat&lng=:lng&radius=:radius').get({lat:location.lat,lng:location.lng,radius:radius}); 
 
     }, 
 
     getJobs: function() { 
 
     return $resource('/ajax/api.cfm?api=job&function=getJobsAssignedtoWorkshop').get(); 
 
     }, 
 
     sendMechanicsJobNotifications: function(mechanics, jobs) { 
 
     return $resource('/ajax/api.cfm?api=job&function=sendMechanicsJobNotifications&mechanics=:mechanics&jobs=:jobs').get({mechanics:mechanics.toString(),jobs:jobs.toString()}); 
 
     }, 
 
     addMechanic: addMechanic, 
 
     removeAllMechanics: removeAllMechanics, 
 
     getAllMechanics: getAllMechanics, 
 
     addJob: addJob, 
 
     removeAllJobs: removeAllJobs, 
 
     getAllJobs: getAllJobs 
 
    } 
 
}); 
 

 

 
mechanicsearch.controller('SearchCtrl', ['$timeout', '$scope', '$window', '$location', '$routeParams', 'filterFilter', 'mechFactory', '$resource', '$element', 
 

 
    function ($timeout, $scope, $window, $location, $routeParams, filterFilter, mechFactory, $resource, $element) { 
 

 
     $scope.place = {}; 
 
     $scope.place.address = null; 
 
     $scope.place.lat = null; 
 
     $scope.place.lng = null; 
 
     $scope.radius = 25; 
 
     $scope.mechanics = []; 
 
     $scope.selection = []; 
 
     $scope.alert = null; 
 
     $scope.showSearchPanel = true; 
 

 
     //Helper method to get selected mechanics 
 
     $scope.selectedMechanics = function selectedMechanics() { 
 
      filterFilter($scope.mechanics, { selected: true }) 
 
     }; 
 

 
     //allow mechanic checkbox to select/deselect on click 
 
     $scope.toggleMechanicSelect = function(mechanic) { 
 
      mechanic.selected = !mechanic.selected; 
 
     } 
 

 
     $scope.goToJobListing = function() { 
 
      $scope.showSearchPanel = false; 
 
      mechFactory.removeAllMechanics(); 
 
      for(var i in $scope.selection) { 
 
      mechFactory.addMechanic($scope.selection[i]); 
 
      } 
 
      $scope.$emit('handleActiveJobsPanel'); 
 
     } 
 

 
     // watch mechanics for changes 
 
     $scope.$watch('mechanics|filter:{selected:true}', function (nv) { 
 
     $scope.selection = nv.map(function (mechanic) { 
 
      return mechanic.objectid; 
 
     }); 
 
     }, true); 
 

 
     //watch the returning google autocomplete details object 
 
     $scope.$watch('details', function() { 
 
      if($scope.details !== undefined && $scope.details !== null) { 
 
      $scope.place.address = $scope.details.formatted_address; 
 
      $scope.place.lat = $scope.details.geometry.location.lat(); 
 
      $scope.place.lng = $scope.details.geometry.location.lng(); 
 
      } 
 
     }); 
 

 
     // watch the $scope.place data for changes 
 
     $scope.$watchCollection('place', function() { 
 
      if($scope.place.lat !== null || $scope.place.lng !== null) { 
 
      $scope.getMechanics(); 
 
      } 
 
     }); 
 

 
     $scope.$watch('radius', function() { 
 
      if(Number.isInteger(parseInt($scope.radius)) ){ 
 
      $scope.getMechanics(); 
 
      } 
 
     }); 
 

 
     $scope.setDirectiveFn = function(directiveFn) { 
 
      $scope.directiveFn = directiveFn; 
 
     }; 
 

 
     $scope.getMechanics = function() { 
 
      mechFactory.getMechanics($scope.place, $scope.radius).$promise.then(
 
      function successfulResult (mechanicsData) { 
 

 
       if (!mechanicsData || !mechanicsData.data.length){ 
 
       $scope.alert = 'Sorry, no mechanic found in "' + $scope.place.address + '" with radius of ' + $scope.radius + '.'; 
 
       $scope.mechanics = []; 
 
       $scope.selection = []; 
 
       } else { 
 
       $scope.alert = mechanicsData.data.length + ' mechanic(s) found in "' + $scope.place.address + '" with radius of ' + $scope.radius + ' km.'; 
 
       $scope.mechanics = mechanicsData.data; 
 
       $scope.selection = []; 
 
       } 
 

 
      }, function failedResult (err) { 
 
       $scope.alert = err.message; 
 
      }); 
 
     }; 
 

 
     //display panel once we have recieved the event 
 
     $scope.$on('activateSearchPanel', function(event, args) { 
 
      $scope.mechanics = []; 
 
      $scope.selection = []; 
 
      $scope.alert = null; 
 
      $scope.showSearchPanel = true; 
 
      $scope.place = {}; 
 
      $scope.radius = 25; 
 
     }); 
 
    } 
 
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-route.min.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-resource.min.js"></script> 
 
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCmN0htBqG3DGo04KKKzC9srgIrhP0Dq5o&libraries=places"></script> 
 
    
 
    
 
<div id="mechanicsearch" data-ng-app="mechanicsearch"> 
 

 
     <div data-ng-controller="SearchCtrl" ng-show="showSearchPanel"> 
 
      <aside class="workshopsearch" > 
 

 
       <form method="post" class="form-inline" role="form"> 
 
       <div class="row"> 
 
         <div class="col-sm-6 form-group input-group-lg"> 
 
          <input type="text" id="geoSearch" ng-model="autocomplete" class="form-control" ng-autocomplete options="{ types: 'geocode', country: 'au', watchEnter: true }" details="details" set-fn="setDirectiveFn(theDirFn)" /> 
 
         </div> 
 
         <div class="col-sm-6 input-group input-group-lg"> 
 
         <input type="text" class="form-control" name="radius" id="radius" placeholder="Radius" data-ng-model="radius"> 
 
         <span class="input-group-btn"><button class="btn btn-go" ng-click="directiveFn()">Go</button</span> 
 
         </div> 
 
        </div> 
 
       </form> 
 
      </aside> 
 
     </div> 
 
     </div>

}

+0

Warum verwenden Sie 'element.val()', wenn Sie ein 'ngModel' an die Eingabe gebunden haben? Warum nicht 'scope.ngModel' verwenden? – fubar

+0

Weil ich offenbar nicht viel darüber weiß wie kantig haha ​​funktioniert. Vielen Dank!!! Dies funktioniert, wenn Sie dies als eine Antwort schlecht markieren markieren Sie es als die angenommene Antwort – matthew

+0

Fertig. Wenn Sie jQuery zum Abrufen von Werten verwenden, müssen Sie die Aufrufe in 'scope. $ Apply()' umbrechen, damit Angular die Änderungen kennt. – fubar

Antwort

3

Warum verwenden Sie element.val() wenn Sie eine ngModel an den Eingang gebunden haben? Warum nicht stattdessen scope.ngModel verwenden?

Verwandte Themen