AngularJS:服务-控制器-视图数据绑定

AngularJS:服务-控制器-视图数据绑定,angularjs,angularjs-scope,angularjs-service,angularjs-controller,Angularjs,Angularjs Scope,Angularjs Service,Angularjs Controller,我试图在服务、控制器和视图之间绑定数据。下面,我为应用程序提供了plunker链接 基本上,“数据服务”具有查找地理位置的功能。该函数设置变量dataService.locationDone 数据服务被分配给“HomeController”中的$scope.data 在home.html中,我引用data.locationDone的值来显示不同的标签 问题是,在dataService中修改locationDone变量后,home.html中的标签不会更改 plunker链接: 服务: store

我试图在服务、控制器和视图之间绑定数据。下面,我为应用程序提供了plunker链接

基本上,“数据服务”具有查找地理位置的功能。该函数设置变量dataService.locationDone

数据服务被分配给“HomeController”中的$scope.data

在home.html中,我引用data.locationDone的值来显示不同的标签

问题是,在dataService中修改locationDone变量后,home.html中的标签不会更改

plunker链接:

服务:

storelocator.factory('dataService', [function() {
    var data = {
        locationDone: 0,
        position: null,
        option: null
    }

    var getLocation = function() {
        data.locationDone = 0;

        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (pos) {
                data.locationDone = 1;
                data.position = pos;
                console.log('got location ', data.locationDone);
            }, function () {
                data.locationDone = 2;
            });
        } else {
            data.locationDone = 3;
        }
    };

    getLocation();

    return data;
}]);
控制器:

storelocator.controller('HomeController', ['$scope', '$location', 'dataService', function ($scope, $location, dataService) {
        $scope.data = dataService;
        console.log('Home ctrl', $scope.data.locationDone);

        $scope.fn = {};
        $scope.fn.showOne = function () {
            $scope.data.option = 3;
            $location.path('/map');
        };

        $scope.fn.showAll = function () {
            $scope.data.option = 99;
            $location.path('/map');
        };
}]);
    $scope.data = {};
    dataService.getLocation().then(function(result){
      $scope.data = result;
    });
视图:


正在等待位置信息。
获取位置时出错。
浏览器不支持位置。
找到最近的三家商店
查找所有商店

您正在更新服务范围中定义的变量
locationDone
。它不会对您在服务中返回的对象产生任何影响(稍后更新时)。而是在服务中预定义对象,并更新引用而不是变量的属性。 还要注意的是,由于您使用的是本机异步api,它在angular上下文之外运行,因此您需要在本例中通过执行
$rootScope.$apply()
手动调用摘要循环,或者只需使用
$timeout
将更新包装在
$timeout
中。然而,更好的方法是在dataService中创建一个api,方法返回
$q
promise

超时

.factory('dataService', ['$timeout', function($timeout) {

    var service = { //Define here;
        locationDone: 0,
        position: null,
        option: null
    }

    var getLocation = function() {
        service.locationDone = 0;

        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (pos) {
              $timeout(function(){
                service.locationDone = 1;
                service.position = pos;
              });
            }, function () {
              $timeout(function(){
                service.locationDone = 2;
              });
            });
        } else {
            service.locationDone = 3;
        }
    };

    getLocation();

    return service; //return it
 }]);
通过qpromise实施:

.factory('dataService', ['$q', function($q) {


    return {
      getLocation:getLocation
    };

   function getLocation() {

        if (navigator.geolocation) {
          var defer = $q.defer();
            navigator.geolocation.getCurrentPosition(function (pos) {
                defer.resolve({locationDone : 1,position : pos})
            }, function () {
               defer.resolve({ locationDone : 2});
            });
          return defer.promise;
        }

        return $q.when({locationDone : 3});

    };


 }]);
在控制器中:

storelocator.controller('HomeController', ['$scope', '$location', 'dataService', function ($scope, $location, dataService) {
        $scope.data = dataService;
        console.log('Home ctrl', $scope.data.locationDone);

        $scope.fn = {};
        $scope.fn.showOne = function () {
            $scope.data.option = 3;
            $location.path('/map');
        };

        $scope.fn.showAll = function () {
            $scope.data.option = 99;
            $location.path('/map');
        };
}]);
    $scope.data = {};
    dataService.getLocation().then(function(result){
      $scope.data = result;
    });
演示

angular.module('app',[]).controller('HomeController',['$scope','$location','dataService',function($scope,$location,dataService){
$scope.data={};
dataService.getLocation().then(函数(结果){
$scope.data=结果;
})
log('Home ctrl',$scope.data.locationDone);
$scope.fn={};
$scope.fn.showOne=函数(){
$scope.data.option=3;
$location.path('/map');
};
$scope.fn.showAll=函数(){
$scope.data.option=99;
$location.path('/map');
};
}]).factory('dataService',['$q',函数($q){
返回{
getLocation:getLocation
};
函数getLocation(){
if(导航器.地理位置){
var defer=$q.defer();
navigator.geolocation.getCurrentPosition(函数(pos)){
defer.resolve({locationDone:1,position:pos})
},函数(){
defer.resolve({locationDone:2});
});
回报、承诺;
}
返回$q.when({locationDone:3});
};
}]);

正在等待位置信息。
获取位置时出错。
浏览器不支持位置。
找到最近的三家商店
查找所有商店

我做了这些更改,但仍然不起作用。我帖子中的plunker链接已更新。我无法真正访问plunker。@Srik
navigator.geolocation.getCurrentPosition
是否为异步右侧和非角度?您可以注入$timeout并包装
data.locationDone=1;data.position=pos内部$timeoutYes。它是异步的,与浏览器一起提供@Srik这是一个非角度的东西,对吗。因此,理想情况下,您需要实现一个承诺模式或在超时时间内完成。尽快更新我的答案