AngularJS:服务 - 控制器 - 查看数据绑定

时间:2015-01-21 18:43:50

标签: angularjs angularjs-scope angularjs-service angularjs-controller

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

基本上' dataService'具有查找地理位置的功能。该函数设置变量dataService.locationDone。

将dataService分配给' HomeController'中的$ scope.data。

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

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

plunker链接:http://embed.plnkr.co/BomSztgC7PzGMzJyDKoF/preview

服务:

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');
        };
}]);

视图:

<div layout="column" layout-align="start center">
    <div layout="column" layout-margin layout-padding>
        <div flex layout layout-margin layout-padding>
            <md-whiteframe flex class="md-whiteframe-z1" layout layout-align="center center" ng-show="data.locationDone==0">
                <span flex>Awaiting location information.</span>
            </md-whiteframe>
            <md-whiteframe flex class="md-whiteframe-z1" layout layout-align="center center" ng-show="data.locationDone==2"><span flex>Error in getting location.</span>
            </md-whiteframe>
            <md-whiteframe flex class="md-whiteframe-z1" layout layout-align="center center" ng-show="data.locationDone==3"><span flex>The browser does not support location.</span>
            </md-whiteframe>
        </div>
        <md-button flex ng-show="data.locationDone==1" class="md-accent md-default-theme md-raised" ng-click="fn.showOne()">Find Nearest Three Stores</md-button>
        <div flex></div>
        <md-button ng-show="data.locationDone==1" flex class="md-accent md-default-theme md-raised" ng-click="fn.showAll()">Find All Stores</md-button>

    </div>
</div>

1 个答案:

答案 0 :(得分:1)

您正在更新服务范围中定义的变量locationDone。它对您在服务期间返回的对象(稍后更新)不会产生任何影响。而是预定义服务中的对象并更新引用而不是变量的属性。 另请注意,由于您使用的是本地异步api,它在角度上下文之外运行,您需要通过在您的情况下执行$rootScope.$apply()来手动调用摘要周期,或者只需使用$timeout将更新包装在{{{ 1}}。然而,更好的方法是使用返回$timeout promise的方法在dataService中创建api。

有超时

$q

使用qpromise实现:

.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
 }]);

在你的控制器中:

.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});

    };


 }]);

<强>演示

&#13;
&#13;
    $scope.data = {};
    dataService.getLocation().then(function(result){
      $scope.data = result;
    });
&#13;
angular.module('app', []).controller('HomeController', ['$scope', '$location', 'dataService', function ($scope, $location, dataService) {
        $scope.data = {};
        dataService.getLocation().then(function(result){
          $scope.data = result;
        })
        
        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');
        };
}]).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});
        
    };

   
 }]);
&#13;
&#13;
&#13;