在Angular服务中重用/重构代码

时间:2014-07-02 14:27:18

标签: javascript json angularjs

我有一个Angular服务,它通过JSON请求获取数据,并将生成的JSON对象发送到许多不同的控制器。

以下代码是此服务的摘要。 postData函数是此服务中许多不同函数之一的示例(几乎所有函数都做同样的事情,但只是发出不同的请求)。此服务中还有其他功能,名为viewDatavisitorData等......

// Service for making JSON requests
    myApp.factory('getData', ['$http', '$cookieStore', 
      function($http, $cookieStore) {
      return {
        postData: function() {

          // Store shared variables   
          var source = 
            ($cookieStore.get('tab') == '#/dashboard/2') ?
            source = $cookieStore.get('1234') :
            source = $cookieStore.get('5678');
          var month = $cookieStore.get('month'),
              year = $cookieStore.get('year');

          // Derive the number of days in the given month
          var month_days = (new Date(year, month, 0)).getDate();

          // Return the promise
          return $http({
            url: base_url + 'string', 
            method: "GET",

            // Set the proper parameters
            params: { 
              id: source,
              start: year + '-' + month + '-01',
              end: year + '-' + month + '-' + month_days,
              interval: 'day'
              }
          });
        },
        ...

我面临的问题是,在每个函数的开头,我必须包含这个代码块,并且每个函数都完全相同。

// Store shared variables   
var source = 
  ($cookieStore.get('tab') == '#/dashboard/2') ?
  source = $cookieStore.get('1234') :
  source = $cookieStore.get('5678');
var month = $cookieStore.get('month'),
    year = $cookieStore.get('year');

// Derive the number of days in the given month
var month_days = (new Date(year, month, 0)).getDate();

然而,很难将其排除在外,因为如果我这样做,当我调用函数时,sourcemonthyear值不会改变使用更新的$cookieStore值。有没有官方的方法我可以在服务共享中拥有多个功能,也许是每次调用函数本身时调用的超级函数?基本上 - 处理这个问题的Angular方法是什么?

3 个答案:

答案 0 :(得分:2)

使它们成为模块级变量并使用'this'来访问它们。以下示例。而不是Angular,这是更多的JavaScript模块方式。

myApp.factory('getData', ['$http', '$cookieStore', 
      function($http, $cookieStore) {
      var factory = {};
      factory.month = ""; // initialize to whatever you want
      factory.year = ""; // initialize to whatever you want

      factory.postData = function() {
           var self = this;
           self.month = $cookieStore.get('month');
           ...
      };

      ...
      ...

      return factory;
}]);

答案 1 :(得分:2)

我不确定这是否是您的目标,但您可以将您的逻辑封装在另一个服务中并将其包含在您希望它在依赖项中使用的服务中;

myApp.factory('getCookieDataSvc', [ '$cookieStore',function($cookieStore){
return {
    getCookieData: function(){
        var source =
            ($cookieStore.get('tab') == '#/dashboard/2') ?
                source = $cookieStore.get('1234') :
                source = $cookieStore.get('5678');
        var month = $cookieStore.get('month'),
            year = $cookieStore.get('year');

        // Derive the number of days in the given month
        var month_days = (new Date(year, month, 0)).getDate();

        return {
            source: source,
            month_days: month_days,
            month: month,
            year: year,
        }
    }
}
});

然后你可以在你的其他服务或控制器中调用它,如下所示:

myApp.factory('getData', ['$http', 'getCookieDataSvc', function($http, getCookieDataSvc) {
return {
    postData: function() {
        var cookieData = getCookieDataSvc.getCookieData();

        // Return the promise
        return $http({
            url: base_url + 'string',
            method: "GET",

            // Set the proper parameters
            params: {
                id: cookieData.source,
                start: cookieData.year + '-' + cookieData.month + '-01',
                end: cookieData.year + '-' + cookieData.month + '-' + cookieData.month_days,
                interval: 'day'
            }
        });
    }
}});

答案 2 :(得分:1)

如果您的Cookie中的值是可变的,您也可以通过这种方式组织代码,以确保始终从$ cookieStore获取最新值。这样您就可以在单个函数中包含$cookieStore代码。

myApp.factory('getData', ['$http', '$cookieStore', 
  function($http, $cookieStore) {

      function getSource() {
        return (getCookieValue('tab') === '#/dashboard/2')
          ? getCookieValue('1234')
          : getCookieValue('5678')
      }

      function getCookieValue(key) {
        return $cookieStore.get(key);
      }

      // Danger ahead, mutations!
      function initValues(source, month, year) {
        source = getSource();
        month = getCookieValue('month');
        year = getCookieValue('year');
      }

      return {
        postData: function() {

          // Store shared variables   
          var source, month, year;
          initValues(source, month, year);

          // Derive the number of days in the given month
          var month_days = (new Date(year, month, 0)).getDate();

          // Return the promise
          return $http({
            url: base_url + 'string', 
            method: "GET",

            // Set the proper parameters
            params: { 
              id: source,
              start: year + '-' + month + '-01',
              end: year + '-' + month + '-' + month_days,
              interval: 'day'
              }
          });
        },
        ...