2013-08-05 40 views
13

Tôi đang sử dụng thư viện ember-i18n để dịch các chuỗi tĩnh được sử dụng trong suốt ứng dụng của tôi. Vì các tệp ngôn ngữ khá lớn, tôi không muốn tải tại ứng dụng, bắt đầu tất cả các từ điển ngôn ngữ có thể có. Do đó, tôi muốn tải từ điển động khi người dùng chọn thay đổi ngôn ngữ. Tôi đã thực hiện triển khai đầu tiên hoạt động khá tốt.Ember: chuyển đổi động sang ngôn ngữ đã chọn (sử dụng thư viện i18n)

Xem http://jsfiddle.net/cyclomarc/RYbNG/7/

Khi bắt đầu ứng dụng, nó được hiển thị bằng tiếng Anh. Bây giờ bạn có thể chọn một trong các khung nhìn (Giới thiệu hoặc Thông tin) và chúng cũng được hiển thị bằng tiếng Anh. Khi bạn nhấp vào 'Hà Lan', từ điển ngôn ngữ tiếng Hà Lan được tải và ứng dụng được chuyển hướng đến tuyến đường chỉ mục bằng ngôn ngữ chính xác.

Dường như các chuỗi ngôn ngữ mới chỉ được sử dụng khi bạn chuyển sang tuyến giả và sau đó quay lại tuyến đường bạn muốn (trong mẫu của tôi, đây luôn là 'chỉ mục').

updateLanguage: function (lang) { 
    var _self = this; 
    //Load correct dictionary and transition to index route 
    $.getScript("http://libraries.azurewebsites.net/locales/dictionary_" + lang + ".js", function() { 
     CLDR.defaultLanguage = lang; 
     _self.transitionToRoute('I18redirect'); 
    }); 
    } 

App.I18redirectRoute = Ember.Route.extend({ 
    activate: function() { 
    this.transitionTo('index'); 
    } 
}); 

Câu hỏi của tôi:

  1. Đây có phải là cách tốt nhất để tải lại một view.template (chuyển đổi sang tuyến đường giả và sau đó vào quá trình chuyển đổi kích hoạt để index)?

  2. Có cách nào để chuyển đổi trở lại tuyến đường mà bạn đã yêu cầu thay đổi ngôn ngữ (cần phải sử dụng thứ gì đó có được (đường dẫn) hay không)?

  3. Tôi cũng muốn dịch các chuỗi 'bên ngoài' div màu đỏ (ổ cắm ứng dụng). Tôi chuyển trở lại chỉ mục, nhưng trong trường hợp đó, mẫu ứng dụng không được vẽ lại ... Điều gì có thể là lý do?

  4. Có phải hành vi mong đợi khi bạn di chuyển ra khỏi mẫu và sau đó nhập lại mẫu, bản thân mẫu sẽ được xây dựng lại với tất cả các chuỗi ngôn ngữ hay chỉ khi nào ngôn ngữ được thay đổi? Làm thế nào có thể xây dựng lại một mẫu với các chuỗi mới được truy tìm trong nhật ký console?

Bất kỳ ý tưởng nào khác để làm cho giải pháp chuyển đổi mạnh mẽ này?

Trả lời

0

Tôi chưa thực hiện bản dịch trong ứng dụng của mình, nhưng tôi định làm như vậy. Vì vậy, tôi cũng quan tâm để biết giải pháp tốt nhất là gì. Tôi sẽ mô tả ý tưởng hiện tại của tôi như thế nào tôi sẽ làm điều đó với kiến ​​thức hiện tại của tôi.

1) Tôi sẽ xác định ngôn ngữ là tuyến đường cấp cao nhất.

App.Router.map(function() { 
    this.resource('language', {path:'/language/:lang_code'}, function() { 
     // All other routes 
    }); 
}); 

Sau đó, thay đổi ngôn ngữ sẽ là liên kết đến Ngôn ngữ với mã ngôn ngữ tương ứng. Tôi cũng sẽ xác định mô hình ngôn ngữ với các thuộc tính mã, tên, cờ vv cho việc này. Điều này cũng sẽ hữu ích khi hiển thị danh sách các nút chọn ngôn ngữ hoặc trình đơn thả xuống.

Ngoài ra khi tải mô hình mạng phụ bạn đã biết langugage là gì và bạn có thể tìm nạp các mô hình bằng ngôn ngữ hiện tại (ví dụ: suy nghĩ về bài đăng blog khác nhau ở mọi ngôn ngữ). Sử dụng this.modelFor ('ngôn ngữ') để có được ngôn ngữ hiện tại trong bất kỳ subroute.

2) Điều này rất khó. AFAIK không có API công khai để nhận URL hiện tại với tất cả các phân đoạn động.Có thuộc tính currentPath trong bộ điều khiển ứng dụng, nhưng nó không bao gồm các biến tuyến động. Ngoài ra còn có một số biến nội bộ Ember, nhưng tôi sẽ không sử dụng chúng khi chúng có thể thay đổi. Bạn cũng có thể điều tra url bộ định tuyến hiện tại: this.get ('router.url'). Ngoài ra, bạn có thể bỏ qua ember và sử dụng window.location.href để đọc URL trực tiếp. Nhưng tôi sẽ không dành quá nhiều thời gian cho việc đó. Người dùng thay đổi ngôn ngữ của họ hiếm khi (thường là lần đầu tiên truy cập) và nó không phải là một vấn đề lớn để chuyển hướng đến tuyến đường chỉ mục về thay đổi ngôn ngữ. Tôi sẽ lưu trữ nó trong một cookie hoặc lưu trữ cục bộ và sau đó không cần phải thay đổi ngôn ngữ sau này. Nếu Ember nghĩ ra cách tốt đẹp và dễ dàng để làm điều đó thì bạn có thể dễ dàng thêm chức năng này sau.

3) Tôi sẽ không đưa bất cứ điều gì vào mẫu ứng dụng vì nó không được dịch. Sử dụng mẫu ngôn ngữ thay vì mẫu ứng dụng và sau đó mọi thứ sẽ được hiển thị lại khi bạn đang chuyển đổi ngôn ngữ.

4) Tôi nghĩ rằng các văn bản không tự động cập nhật vì chúng hiện không bị ràng buộc hai chiều. Nhưng nó là tốt, bởi vì nó không phải là một ý tưởng rất tốt để có hai cách ràng buộc cho tất cả các văn bản vì nó có thể làm cho hệ thống chậm. Vì vậy, chỉ cần đặt các ngôn ngữ như tuyến đường cấp cao nhất và tất cả mọi thứ sẽ làm việc tốt :)

+0

Đề xuất tốt. Tôi sẽ phân tích tác động của việc xác định ngôn ngữ là tuyến đường cấp cao nhất. Không chắc chắn rằng điều này sẽ không tạo ra một số ma sát ở nơi khác ... – cyclomarc

0

Bạn có thể sử dụng phương pháp rerender() về quan điểm, cách này bạn sẽ không phải chuyển sang một url giả:

updateLanguage: function(lang) { 

    //Send xhr to get a dictionary for corresponding language 
    this.getDictionary(lang).then(successCb, failureCb); 

    //If dictionary was retrieved, set translations property and 
    function successCb(response) { 
     Ember.I18n.translations = response; 
     $.each(Ember.View.views, function(index, view) { 
      view.rerender(); 
     }); 
    }; 

    function failureCb(response) { 
     console.error('Dictionary for this language is not available'); 
    }; 
} 
0

Tôi đã thử tất cả các cách được liệt kê ở đây và có nhiều vấn đề khác nhau với tất cả chúng. Tôi đã tìm thấy một bản hack thanh lịch hơn để thực hiện công việc này.

CAVEAT: Tính năng này chỉ hoạt động nếu bạn đang dùng Ember sử dụng Rails (nhưng có thể được điều chỉnh để làm việc với bất kỳ khung bên máy chủ nào).

Trong Rails, đá quý i18n-js tích hợp với ngôn ngữ mặc định của Rails. Chuyển đổi động trong Ember là một nỗi đau lớn vì bạn phải vẽ lại tất cả các chế độ xem hoặc đặt lại ứng dụng theo cách thủ công để cập nhật ngôn ngữ khi I18n.locale được thay đổi.

Cách tốt nhất tôi đã tìm thấy để làm điều đó là xác định miền địa phương bằng cách sử dụng các thông số được đặt trên Rails, trước khi Ember thậm chí tải.

RAILS cấu hình:

Hãy ember # controller index nhìn hành động của bạn như thế này:

def index 
    if params[:locale] 
    I18n.locale = params[:locale] 
    end 
end 

Sau đó, trong html mẫu của bạn, thêm dòng này của javascript:

<html> 
    <head> 
    <%= stylesheet_link_tag :application, :media => :all %> 
    <%= stylesheet_link_tag "application", 'http://fonts.googleapis.com/css?family=Roboto:400,300,300italic,100,700' %> 
    <%= stylesheet_link_tag "application", 'http://fonts.googleapis.com/css?family=Roboto+Condensed:400,300,300italic' %> 
    <%= javascript_include_tag :application %> 
    <title>Review Blaster 9000</title> 

<!-- SET LOCALE USING RAILS PARAMETER PARSING --> 
    <script>I18n.locale = '<%=I18n.locale%>';</script> 
<!-- END SET LOCALE --> 

    </head> 
    <body> 

<!-- Start Ember.js --> 
     <%= yield %> 
<!-- End Ember.js --> 

    </body> 
</html> 

Sau đó, trong mẫu của bạn, chỉ định trình chuyển đổi ngôn ngữ như sau:

<a href='/?locale=en'>English</a> 
<a href='/?locale=es'>Spanish</a> 
...etc... 

Nhấp vào các liên kết đó sẽ dẫn đến việc làm mới hoàn toàn ứng dụng. Đường ray sẽ phân tích tham số, đặt I18n và sau đó Ember sẽ bắt đầu với giá trị chính xác đã được đặt trước, vì vậy mọi thứ sẽ vẽ chính xác.