如何删除控制器之间的重复共享功能

时间:2016-02-13 00:21:04

标签: angularjs

我需要在控制器之间使用i18n翻译功能。

因此每个控制器应该有getCityNamegetCountryName将其翻译成正确的语言。

我尝试使用Angular服务来减少重复。

如您所见,我仍然需要分别在两个控制器中定义这些功能。

在我的情况下是否可以删除控制器中定义函数的重复?

由于

Departure.html

  <div  ng-repeat="departure in departures_lst">
    <div class="panel-title">
      <h5>{{getCountryName(departure.country)}}</h5>
    </div>
            <li  ng-repeat="city in departure.cities">
              <a ng-click="get_destinations(city)">
                {{getCityName(city)}}
              </a>
           </li>
  </div>

Arrival.html

  <div  ng-repeat="arrive in arrives_lst">
    <div class="panel-title">
      <h5>{{getCountryName(arrive.country)}}</h5>
    </div>
            <li  ng-repeat="city in arrive.cities">
              <a ng-click="get_destinations(city)">
                {{getCityName(city)}}
              </a>
           </li>
  </div>

Angular js

App.service('I18nService', function () {
    this.getCountryName = function (country_name) {
      return I18n.t("country." + country_name) + country_name
    }
    this.getCityName = function (city_name) {
      return I18n.t("city." + city_name) + city_name
    }
});

App.controller("departures_ctrl", function($scope, I18nService, $location, $http) {
    $scope.getCountryName = function(country_name){
      return I18nService.getCountryName(country_name);
    }
    $scope.getCityName = function(city_name){
      return I18nService.getCityName(city_name);
    }
});

App.controller("arrivals_ctrl",  function($scope, $route, I18nService, $routeParams, $http, $window, $location) {
    $scope.getCountryName = function(country_name){
      return I18nService.getCountryName(country_name);
    }
    $scope.getCityName = function(city_name){
      return I18nService.getCityName(city_name);
    }


});

2 个答案:

答案 0 :(得分:1)

避免重复的一种方法是在服务功能中添加一个参数。

你可以这样写:

app.controller('FooCtrl', function($scope, TranslationService){

  $scope.getName = function(name, flag){
   TranslationService.getName(name,flag); 
  }

});

app.controller('BarCtrl', function($scope, TranslationService){

  $scope.getName = function(name, flag){
   TranslationService.getName(name,flag); 
  }

});

app.factory('TranslationService', function(){

  return {
    getName: function(name,flag){
      if(flag == 'city'){
          //...
      } 
      else{
        //...  
      }
    }
  }
})

在HTML视图中,您可以使用:

<div ng-app="myApp" ng-controller="FooCtrl">

  <p>{{getName(obj.city, 'city')}}</p>

</div>

如果你想避免两次在两个控制器中声明getName函数,你可以将函数分配给$rootScope但IMO它不是一个理想的解决方案,因为它可以使代码不太可读。

答案 1 :(得分:0)

虽然它可能会混合2个职责(参见https://softwareengineering.stackexchange.com/a/222673),但您可以考虑将服务移到指令中并在模板中使用它,如此

<div  ng-repeat="departure in departures_lst">
    <div class="panel-title">
      <h5><country-name ng-model="departure.country"></country-name></h5>
    </div>
    <li  ng-repeat="city in departure.cities">
      <a ng-click="get_destinations(city)">
         <city-name ng-model="departure.country"></city-name>
      </a>
    </li>
</div>

这样,您只需将服务注入指令并使用它将属性值转换为正确的值。

如果您只是将它用于显示(即您没有将转换后的值用于代码的任何其他部分),我会全心全意地推荐。