【问题标题】:Angular services don't work when moved to separate files移动到单独的文件时,Angular 服务不起作用
【发布时间】:2017-05-11 02:51:17
【问题描述】:

我的演示 MEAN 应用程序(在 Cloud9 中使用它)有问题:当我将服务移动到单独的文件时,该应用程序无法运行。 这有效:

angular.module('locatorApp', [])

var locationListCtrl = function($scope, locatorData, geolocation) {
  $scope.getData = function(position) {
    var lat = position.data.lat;
    var lng = position.data.lon;
    locatorData.locationByCoords(lat,lng)
      .then(function(data) {
        $scope.data = {locations: data.data};
      })
      .catch(function(error) {
        console.log(error);
      });
  };

  geolocation.getPosition($scope.getData);
};

var locatorData = function($http) {
  var locationByCoords = function (lat, lng) {
    return $http.get('/api/locations?lng=' + lng + '&lat=' + lat);
  };
  return {
    locationByCoords : locationByCoords
  };
};

var geolocation = function($http) {
  var geoAPIURL = 'http://ip-api.com/json/?fields=lat,lon,status';
  var getPosition = function(cbSuccess, cbError) {
      $http.get(geoAPIURL).then(cbSuccess, cbError);
  };
  return {
    getPosition : getPosition
  };
};

angular
  .module('locatorApp')
  .controller('locationListCtrl', locationListCtrl)
  .service('locatorData', locatorData)
  .service('geolocation', geolocation);

然后我把它分成单独的文件, app.js:

angular
  .module('locatorApp', ['ngRoute'])
  .config(['$routeProvider', config]);

function config($routeProvider) {
  $routeProvider
    .when('/', {
      templateUrl: 'home/home.view.html',
      controller: 'homeCtrl',
      controllerAs: 'vm'
    })
    .otherwise({redirectTo: '/'});
}

home.controller.js:

angular
  .module('locatorApp')
  .controller('homeCtrl', homeCtrl);

function homeCtrl(locatorData, geolocation) {
  var vm = this;
  vm.pageHeader = {
    title: 'Locator',
  };

  vm.getData = function(position) {
    var lat = position.data.lat;
    var lng = position.data.lon;
    locatorData.locationByCoords(lat,lng)
      .then(function(data) {
        vm.data = {locations: data.data};
      })
      .catch(function(error) {
        console.log(error);
      });
  };

  geolocation.getPosition(vm.getData);
}

geolocation.service.js:

angular
 .module('locatorApp')
 .service('geolocation', geolocation);

var geolocation = function($http) {
  var geoAPIURL = 'http://ip-api.com/json/?fields=lat,lon,status';
  var getPosition = function(cbSuccess, cbError) {
      $http.get(geoAPIURL).then(cbSuccess, cbError);
  };
  return {
    getPosition : getPosition
  };
};

locatorData.service.js:

angular
 .module('locatorApp')
 .service('locatorData', locatorData);

var locatorData = function($http) {
  var locationByCoords = function(lat, lng) {
    return $http.get('/api/locations?lng=' + lng + '&lat=' + lat);
  };
  return {
    locationByCoords : locationByCoords
  };
};

layout.jade 中的链接:

// files in 'public' folder
script(src='/angular/angular.min.js')
script(src='/lib/angular-route.min.js')

// files in 'app_client' folder 
script(src='/app.js')
script(src='/home/home.controller.js')
script(src='/common/services/geolocation.service.js')
script(src='/common/services/locatorData.service.js')

express app.js 中的静态变量:

app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'app_client')));

出现如下错误:

错误:[ng:areq] http://errors.angularjs.org/1.6.1/ng/areq?p0=fn&p1=not%20aNaNunction%2C%20got%20undefined

我搜索了文档和教程,但无法弄清楚服务定义有什么问题。

【问题讨论】:

  • 你的服务实际上是作为工厂构建的
  • 是的,我在谷歌上搜索模块结构时发现了它,但它应该可以工作,对吗?
  • getPosition() 不返回任何东西
  • 这也让我感到困惑,但事实证明它可以在单文件解决方案中工作(非常第一个列表),我认为由于使用 .then()
  • 但我也尝试用 return 重写它,但没有任何改变。我做了很多实验,当我将任何服务作为参数传递给 homeCtrl 函数时,一切都失败了

标签: angularjs node.js express pug


【解决方案1】:

问题是您在声明之前使用变量。

locatorDatageolocation 被定义为函数表达式。因此,它们在声明位置之前是未定义的。

您可以更改注册服务和定义函数的顺序,因为它在包含所有代码的原始文件中

var locatorData = function($http) {
...
};

angular
 .module('locatorApp')
 .service('locatorData', locatorData);

或者你可以使用函数声明(不是函数表达式)

angular
 .module('locatorApp')
 .service('locatorData', locatorData);

function locatorData($http) {
...
};

【讨论】:

    【解决方案2】:

    这种方式绑定在宿主对象中镜像,原始值不能使用显示模块模式单独更新。

    试试这个

    geolocation.service.js:

    angular
    .module('locatorApp')
    .service('geolocation', geolocation);
    
     function geolocation ($http) {
        //include these four lines of code
        var MirrorFunc = {
        getPosition : getPosition 
    };
      return MirrorFunc;
        //till here 
      var geoAPIURL = 'http://ip-api.com/json/?fields=lat,lon,status';
      function getPosition (cbSuccess, cbError) {
        $http.get(geoAPIURL).then(cbSuccess, cbError);
      }
    };
    

    同样适用于 locatorData.service.js:

    angular
    .module('locatorApp')
    .service('locatorData', locatorData);
    
     function locatorData ($http) {
      //include these four lines of code
      var MirrorFunc = {
       locationByCoords : locationByCoords 
     };
     return MirrorFunc ;
    //till here 
     function locationByCoords  (lat, lng) {
        return $http.get('/api/locations?lng=' + lng + '&lat=' + lat);
     }  
    };
    

    您可以访问 John Papa 的 Angular 风格指南 https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#services

    【讨论】:

    • 感谢链接!一定是搞错了,返回MirrorFunc后的代码无法访问
    • 我做了一些改变。有同样的问题吗?
    • 返回 MirrorFunc 后的函数仍然无法访问
    【解决方案3】:

    尝试更改包含脚本的顺序。 看起来您正在调用包含服务调用的控制器,即使您没有将服务加载到页面。

    // files in 'app_client' folder 
    script(src='/app.js')
    script(src='/common/services/geolocation.service.js')
    script(src='/common/services/locatorData.service.js')
    script(src='/home/home.controller.js')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      • 1970-01-01
      • 2021-10-26
      • 1970-01-01
      相关资源
      最近更新 更多