在AngularJS指令中,如何设置父控制器的属性?

时间:2013-01-08 16:38:23

标签: angularjs

这是一个显示我正在尝试做的事情的jsFiddle:http://jsfiddle.net/P3c7c

我正在使用Google Places AutoComplete小部件来获取纬度/经度坐标,然后我希望在后续搜索功能中使用它。考虑到需要向元素添加事件监听器,似乎实现这一点的正确方法是使用指令,并使用指令的链接函数附加监听器。但是,在这个监听器内部,我需要它来设置SearchForm控制器的位置属性,它是它的父级。我还没弄明白如何建立这种联系。这是相关的代码块:

    /* Controllers */
    function SearchForm($scope){
        $scope.location = ''; // <-- this is the prop I wish to update from within the directive

        $scope.doSearch = function(){
            if($scope.location === ''){
                alert('Directive did not update the location property in parent controller.');
            } else {
                alert('Yay. Location: ' + $scope.location);
            }
        };
    }

    /* Directives */
    angular.module('OtdDirectives', []).
        directive('googlePlaces', function(){
            return {
                restrict:'E',
                replace:true,
                transclude:true,
                scope: {location:'=location'}, // <--prob something wrong here? i tried @/& too, no luck
                template: '<input id="google_places_ac" name="google_places_ac" type="text" class="input-block-level"/>',
                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();
                        // THIS IS THE STRING I WANT TO SAVE TO THE PARENT CONTROLLER
                        var location = place.geometry.location.lat() + ',' + place.geometry.location.lng();
                        // THIS IS NOT DOING WHAT I EXPECT IT TO DO:
                        $scope.location = location;
                    });
                }
            }
        });

提前致谢。

1 个答案:

答案 0 :(得分:3)

两个小的修正,它应该有效:

<google-places location="location"></google-places>

当您在指令中设置位置时,您还需要执行$scope.$apply()

$scope.$apply(function() {
    $scope.location = location;
});

你必须做$apply()因为事件发生在角度摘要循环之外,所以你必须让角度知道范围内的某些东西已经改变,它需要“消化”它的双向绑定和其他内部异步的东西。

此外,我认为您不需要transclude:true

http://jsfiddle.net/P3c7c/1/