2016-02-13 85 views
4

我需要在控制器之間使用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> 

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


}); 

回答

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不是一個理想的解決方案,因爲它可以使代碼更不可讀。

+0

謝謝〜我會稍後再嘗試,但它看起來有點複雜,並把太多的邏輯放在這麼簡單的事情:) – newBike

+0

@newBike很高興我幫了你。是的,只需要替換兩個函數就可能有點過於複雜,但它使您可以將您的函數邏輯全部放在一個地方而不是兩個地方,從長遠來看可以幫助您維護代碼或實施一些新的邏輯。 – fbid

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> 

這樣的話,你只注入你的服務插入指令並使用它來將您的屬性值轉換爲適當的值。

如果你只是用它來顯示(即你沒有在你的代碼的任何其他部分使用轉換後的值),我會推薦這個全心全意的。