【问题标题】:Calling methods from directive从指令调用方法
【发布时间】:2015-12-04 00:47:21
【问题描述】:

所以我正在尝试习惯 Angular,并且在尝试调用指令(谷歌地图https://github.com/davidepedone/angular-google-places-map)和执行反向地理编码时遇到了一些麻烦。我认为这将是一个更一般的指令问题。

我试图在指令中调用一个函数来更新谷歌地图的地点信息以及地图。我脑海中的想法是,我需要通过控制器传递一个变量,将该变量的范围限定为指令,然后指令将运行该函数?

更新:

 <div class="row">
 <places-map selectedid="selectid(place.id)"></places-map>
 </div>
 <button ng-click="selectid(place.id)">{{place.id}}</button> </div> 

通过这个点击我想去控制器,

$scope.selectid= function (pickplaceid){
   $scope.selectedid(pickplaceid);
}

那么 selectplaceid 应该在指令的范围变量中。

        scope: {
            customCallback: '&?',
            picked: '=?',
            address: '=?',
            fallback: '=?',
            mapType: '@?',
            readonly: '@?',
            responsive: '@?',
            draggable: '@?',
            toggleMapDraggable: '=?',
            placeNotFound: '=?',
            updateMarkerLabel: '=?',
            selectedid:'='
        },

并且可以这样调用我的方法:

 link: function ($scope, element, attrs, controller) {
 //everything else from angular-google-places

            $scope.selectedid= function (selectedplace)
            {
 ///Whatever I want to do to geocode with the placeid
            }

我认为我可能完全错误地这样做了,因为指令调用根本没有运气。我正在尝试根据我单击的位置更新我的地图,并从 placeId 中提取该特定地点的信息。任何帮助都会很棒。

【问题讨论】:

  • 您在指令中创建了一个隔离范围,因此它不知道控制器中的变量。你需要在html中传递你需要的变量:
  • 这不是说你的范围selectplaceid=place.id吗?它将如何调用函数 selectplaceid?
  • 实际上,在重新阅读您的问题后,我认为您可以在控制器中将$scope.selectplaceid = pickplaceid; 更改为$scope.selectplaceid(pickplaceid);,以调用指令中的方法。但是,您仍然需要将该函数传递给 HTML 中的指令,因为您已经创建了一个隔离范围。查看文档中传递 customerInfo 的示例:docs.angularjs.org/guide/directive
  • 是的,这就是我的问题,如何从 html 端调用隔离指令作用域函数?我知道我们将 $scope 设置为 customerInfo 示例中显示的值但功能似乎有点不同?
  • 哦对了,它似乎需要使用&amp; 作为函数参数传递。我知道我做过类似的事情,但不是在我的工作 PC atm 上。也许这是一个有用的例子:weblogs.asp.net/dwahlin/…

标签: javascript angularjs google-maps angularjs-directive angularjs-scope


【解决方案1】:

我的工作几乎相同,我使用接收 placeId 的服务解决了它(在我的代码中,它称为 addressId,但它是 Google Maps 期望的 placeId)。在我的服务中,我使用 placeId 来检索地址详细信息:

  app.service('AddressDetailsService', ['$q', function ($q) {

    this.placeService = new google.maps.places.PlacesService(document.getElementById('map'));

    this.getDetails = function (addressId, address) {
      var deferred = $q.defer();

      var request = {
        placeId: addressId
      };

      this.placeService.getDetails(request, function (place, status) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
          address.placeId = addressId;
          address.street = getAddressComponent(place, 'route', 'long');
          address.countryCode = getAddressComponent(place, 'country', 'short');
          address.countryName = getAddressComponent(place, 'country', 'long');
          address.cityCode = getAddressComponent(place, 'locality', 'short');
          address.cityName = getAddressComponent(place, 'locality', 'long');
          address.postalCode = getAddressComponent(place, 'postal_code', 'short');
          address.streetNumber = getAddressComponent(place, 'street_number', 'short');
          address.latitude = place.geometry.location.lat();
          address.longitude = place.geometry.location.lng();

          if (address.streetNumber) {
            address.streetNumber = parseInt(address.streetNumber);
          }
          deferred.resolve(address);
        }
      });

      return deferred.promise;
    };

    function getAddressComponent(address, component, type) {
      var country = null;
      angular.forEach(address.address_components, function (addressComponent) {
        if (addressComponent.types[0] === component) {
          country = (type === 'short') ? addressComponent.short_name : addressComponent.long_name;
        }
      });

      return country;
    }
  }]);

然后你注入它并从你的指令中调用服务。这是我使用的那个,你可能需要适应它,但你明白这个想法。我没有使用链接函数,而是使用了指令控制器:

  .directive('mdAddressDetails', function mdAddressDetails() {
    var directive = {
      restrict: 'EA',
      scope: {
        address: '='
      },
      bindToController: true,
      templateUrl: 'modules/address/addressDetails.html',
      controller: AddressDetailsController,
      controllerAs: 'dir'
    };

    AddressDetailsController.$inject = ['AddressDetailsService', '$q'];

    function AddressDetailsController(AddressDetailsService, $q) {
      var dir = this;

      dir.selectAddress = selectAddress;

      function selectAddress(address) {
        if ((address) && (address.place_id)) {
          AddressDetailsService.getDetails(address.place_id, dir.address).then(
            function (addressDetails) {
              dir.address = addressDetails;
            }
          );
        }
      }
    }

    return directive;
  });

然后你只需使用想要的参数调用指令:

  <md-address-details address="myAddress"></md-address-details>

【讨论】:

  • 放置控制器而不是链接控制器很有趣。由于我已经有一个指令 我对您的 ng-click 如何调用该指令感到困惑?
  • 对不起!错过了那部分。我想它会是这样的:stackoverflow.com/questions/15613992/… 所以你实际上在你的指令中有 ng-click,并在那里处理它。
  • 所以我有点困惑,这是如何使用 place-map 指令的?由于我的指令是谷歌地图的自动完成功能,而且我有一个与指令分开的 ng-click,我很困惑它是如何工作的?我在这里看到的是您的指令将调用将提取地图数据的服务。
  • 我的指令也使用了自动完成,但我删除了它,因为我认为你不会使用它。你想达到什么目的?我们有一个带有地图的自动完成功能,当用户选择一个地址时,我们会检索详细信息。这就是你想要做的吗?
  • 所以我们有一个自动完成。我们将自动完成的数据保存在我们的数据库中。然后在一边,我们有一个保存的 placeid 表。单击其中一个 placeid 时,它会返回地图并更新位置。因此,从自动完成保存的信息中对保存的 placeid 进行地理编码。希望能解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-30
  • 2018-04-22
  • 1970-01-01
  • 2013-05-16
相关资源
最近更新 更多