无法在模板和指令之间进行角度绑定

时间:2015-07-01 03:53:55

标签: javascript angularjs

我试图将用户当前的坐标从我的控制器中导入我的模板,并从那里进入我的指令。上半部分有效,但我不能让下半场为我的生活工作。在指令中,我也试过' ='和lat = currentLat,以及范围/ $ scope。发生了什么事?

控制器:

var posOptions = { timeout: 5000, enableHighAccuracy: true, maximumAge: 5000 };
$cordovaGeolocation.getCurrentPosition(posOptions)
    .then(function (location) {
        $scope.currentLat = location.coords.latitude;
        $scope.currentLong = location.coords.longitude;
        console.log($scope.currentLat, $scope.currentLong);
    });

模板:

<div id="map" zoom="16" bgeo lat="{{currentLat}}" lng="{{currentLong}}">

指令:

.directive('bgeo', ['$cordovaGeolocation', '$cordovaBackgroundGeolocation', '$http', function ($cordovaGeolocation, $cordovaBackgroundGeolocation, $http) {
return {
    scope: {
       lat: '@',
       lng: '@'
   },
    link: function (scope) {
        console.log("directive: ", scope.lat, scope.lng);
    }
}}])

可以在此处找到测试应用的完整代码:https://github.com/sahiltalwar88/binding-geolocation-issue

2 个答案:

答案 0 :(得分:4)

在模板中使用@时,它是一次性字符串绑定。由于您正在等待异步.getCurrentPosition完成,因此直到它们已在指令中链接之后才会更新。只有在编译指令时才会调用链接函数。

相反,您需要推迟指令的加载,直到加载范围值。您可以通过ng-if

将指令保留在DOM之外来阻止编译指令
<div bgeo ng-if=loaded lat={{currentLat}} lng={{currentLng}}>

loaded设置为true之前,该指令不会被编译或链接,您可以在.getCurrentPosition回调中执行此操作:

http://plnkr.co/edit/eYWXCA5UE6dUu9RM5mdj?p=preview

您还可以在隔离范围定义中将{em>数据绑定与=一起使用。但请注意,该指令在最初编译后仍然只是链接,因此console.log将被过早调用。如果您在模板或控制器中使用绑定值,则更有意义 - 特别是如果您将更改它们并将其传播回父控制器。

http://plnkr.co/edit/ZXwDr3Tq3w046G7FM4mK?p=preview

答案 1 :(得分:0)

这就是最终的工作:

模板:

<ion-scroll zooming="true" direction="xy" style="width:90%">
   <div ng-if="loaded" bgeo lat="currentLat" lng="currentLong">
       <div id="map" style="width: 600px; height: 500px;"></div>
   </div>
</ion-scroll>

控制器:

angular.module('testApp.controllers', ['ionic', 'ngCordova.plugins.geolocation', 'ngCordova.plugins.backgroundGeolocation'])

.controller('MapCtrl', ['$scope', '$ionicPopup', '$cordovaGeolocation', '$cordovaBackgroundGeolocation', '$timeout', '$http', 
               function ($scope, $ionicPopup, $cordovaGeolocation, $cordovaBackgroundGeolocation, $timeout, $http) {
    $scope.loaded = false;

    var posOptions = { timeout: 5000, enableHighAccuracy: true, maximumAge: 5000 };
    $cordovaGeolocation.getCurrentPosition(posOptions)
        .then(function (location) {
            $scope.currentLat = location.coords.latitude;
            $scope.currentLong = location.coords.longitude;
            $scope.loaded = true;
        });
}])

指令:

.directive('bgeo', ['$cordovaGeolocation', '$cordovaBackgroundGeolocation', '$http', 
           function ($cordovaGeolocation, $cordovaBackgroundGeolocation, $http) {
    return {
        scope: {
           lat: '=',
           lng: '='
       },
        link: function (scope) {
            console.log("directive: ", scope.lat, scope.lng);
                myLatLng = new google.maps.LatLng(scope.lat, scope.lng);
                mapOptions = {
                    zoom: 16,
                    center: myLatLng
                };
                map = new google.maps.Map(document.getElementById('map'), mapOptions);
                marker = new google.maps.Marker({
                    position: myLatLng,
                    map: map,
                    draggable: false,
                    icon: 'small-orange-pin.png'
                });
        }
    }
}])