传递“ $ routeParams”的最佳方法是什么?到AngularJS中的服务? [英] What's the best way to pass "$routeParams" to a Service in AngularJS?

查看:92
本文介绍了传递“ $ routeParams”的最佳方法是什么?到AngularJS中的服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的angularJs应用程序中,我可以在控制器中获取$ routeParams,但如何在服务中获取它?我想遵循关注点分离方法,并将http请求与控制器分开。

In my angularJs app I'm able to get $routeParams in the controller but how should I get it in a service? I would like to follow the separation of concerns approach and keep my http requests separate from my controllers.

我在 app中尝试了以下操作.js ,但出现错误:$ injector:unpr
未知提供程序

var app = angular.module('app', ['ngRoute']);  // TODO: 'ngAnimate', 'ui.bootstrap' 

app.config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider){

    $routeProvider
        .when('/', {
            templateUrl: '/app/static/home.html',
            controller: 'mainController as mainCtrl'

        })
        .when('/match/id-:matchId', {
            templateUrl: '/app/components/match/matchView.html',
            controller: 'matchController as matchCtrl'
        });

    // use the HTML5 History API
    $locationProvider.html5Mode(true);
}]);

app.controller('matchController', ['$routeParams', 'matchService', function ($routeParams, matchService) {
    var matchCtrl = this;
    matchCtrl.matchId = $routeParams..matchId;  // how can I move this into the service

    this.getMatchId = function ()
    {
        return matchCtrl.matchId;
    };

    var promise = matchService.getMatch();
    promise.then(function (data)
    {
        matchCtrl.match = data;
    });
}])

app.service("matchService", function ($http, $q, matchController)
{
    var matchId = matchController.getTable();

    var url = 'https://jsonplaceholder.typicode.com/posts/1';
    $http({
        method: 'GET',
        cache: true,
        url: url,
        headers: {  
           'Content-Type': 'application/json;charset=UTF-8'  
        }
    }).
    success(function(response) {
        //your code when success
        // lgTblCtrl.amateurTable = data;
        deferred.resolve(response);
        console.log('SUCCESS!');
    }).
    error(function(response) {
        //your code when fails
        console.log('ERROR!');
    });

    this.getTable = function ()
    {
        return deferred.promise;
    };
})


推荐答案

首先,您已创建循环引用,其中将 matchService 注入到 matchController matchController 被注入到 matchService 中。

First of all, you have created cyclic reference where the matchService is injected into the matchController and matchController is injected into the matchService.

服务是 singleton 对象,创建一次,该对象与注入对象时传递的实例相同。相反,将为每个视图创建一个控制器。因此,如果您有两个使用同一控制器的视图,则将通过不共享$ scope来创建并使用单独的控制器实例。因此,如果将控制器注入服务,则会再次创建另一个实例并将其注入服务。

Service is a singleton object, created once which is the same instance passed wherever it gets injected. On contrast, controller will be created one per view. So if you have two views using the same controller, separate controller instances will be created and used by them by not sharing the $scope. So, if you inject a controller to the service, again another instance will be created and injected to the service.

由于服务应该是通用的并且独立于控制器,您不应按照最佳编码惯例将控制器注入任何服务。

Since a service should be generic and independent of the controller, you should not inject controller to any service as per the best coding practice.

此外,由于服务是 singleton ,并且可以被任何人使用控制器或视图,它应该独立于视图/路线,因此您不能在服务内部使用 $ routeParams

Also, as a service is singleton and can be used by any controller or view, it should be independent to the view/route and hence you can't use $routeParams inside the service.

相反,您可以将 $ routeParams.matchId 作为服务方法的参数。

Instead, you can pass the $routeParams.matchId as an argument to the service method.

注意:在您的控制器中,您使用了 $ routeParams..matchId 双点(..)而不是 $ routeParams.matchId

Note: In your controller, you have used $routeParams..matchId with double dots (..) instead of $routeParams.matchId.

此外,也没有控制器使用的 matchService 中的matchService.getMatch

Also, there is no matchService.getMatch inside the matchService which used by the controller.

您必须纠正它们。

我已经按照我的解释更改了下面的代码,然后看看。

I have changed the code below as I explained and have a look.

var app = angular.module('app', ['ngRoute']);  // TODO: 'ngAnimate', 'ui.bootstrap' 

app.config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider){

    $routeProvider
        .when('/', {
            templateUrl: '/app/static/home.html',
            controller: 'mainController as mainCtrl'

        })
        .when('/match/id-:matchId', {
            templateUrl: '/app/components/match/matchView.html',
            controller: 'matchController as matchCtrl'
        });

    // use the HTML5 History API
    $locationProvider.html5Mode(true);
}]);

app.controller('matchController', ['$routeParams', 'matchService', function ($routeParams, matchService) {
    var matchCtrl = {};

    var promise = matchService.getMatch($routeParams.matchId);
    promise.then(function (data)
    {
        matchCtrl.match = data;
    });
}])

app.service("matchService", function ($http, $q)
{
    var deferred = $q.defer();

    function getMatch(matchId) {
      var url = 'https://jsonplaceholder.typicode.com/posts/1';
      return $http({
        method: 'GET',
        cache: true,
        url: url,
        headers: {  
           'Content-Type': 'application/json;charset=UTF-8'  
        }
      }).
      then(function(response) {
        //your code when success
        // lgTblCtrl.amateurTable = data;
        deferred.resolve(response);
        console.log('SUCCESS!');
      }, function(response) {
        //your code when fails
        console.log('ERROR!');
        deferred.reject(response);
      });

      return deferred.promise;
    }

    this.getMatch = getMatch;
})

这篇关于传递“ $ routeParams”的最佳方法是什么?到AngularJS中的服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆