javascript - नियंत्रकों में कोणीय-अनुवाद के लिए सही उपयोग




angularjs angular-translate (4)

मैं एक कोणीयजेएस अनुप्रयोग में i18n के लिए angular-translate का उपयोग कर रहा हूं।

प्रत्येक एप्लिकेशन दृश्य के लिए, एक समर्पित नियंत्रक है। नीचे नियंत्रकों में, मैंने मूल्य को पृष्ठ शीर्षक के रूप में दिखाया है।

कोड

एचटीएमएल

<h1>{{ pageTitle }}</h1>

जावास्क्रिप्ट

.controller('FirstPageCtrl', ['$scope', '$filter', function ($scope, $filter) {
        $scope.pageTitle = $filter('translate')('HELLO_WORLD');
    }])

.controller('SecondPageCtrl', ['$scope', '$filter', function ($scope, $filter) {
        $scope.pageTitle = 'Second page title';
    }])

मैं angular-translate-loader-url एक्सटेंशन का उपयोग कर अनुवाद फ़ाइलों को लोड कर रहा हूं।

मुसीबत

प्रारंभिक पृष्ठ लोड पर, उस कुंजी के अनुवाद के बजाय अनुवाद कुंजी दिखाई जाती है। अनुवाद Hello, World! , लेकिन मैं HELLO_WORLD देख रहा हूँ।

दूसरी बार जब मैं पेज पर जाता हूं, तो सब ठीक है और अनुवादित संस्करण दिखाया गया है।

मुझे लगता है कि इस मुद्दे को इस तथ्य के साथ करना है कि नियंत्रक अभी तक लोड नहीं किया गया है जब नियंत्रक $scope.pageTitle को मान निर्दिष्ट कर $scope.pageTitle

टिप्पणी

<h1>{{ pageTitle | translate }}</h1> का उपयोग करते समय <h1>{{ pageTitle | translate }}</h1> और $scope.pageTitle = 'HELLO_WORLD'; , अनुवाद पहली बार सही काम करता है। इसके साथ समस्या यह है कि मैं हमेशा अनुवाद का उपयोग नहीं करना चाहता (उदाहरण के लिए। दूसरे नियंत्रक के लिए मैं केवल कच्ची स्ट्रिंग पास करना चाहता हूं)।

सवाल

क्या यह एक ज्ञात मुद्दा / सीमा है? यह कैसे हल किया जा सकता है?


अनुशंसित: नियंत्रक में अनुवाद न करें, अपने विचार में अनुवाद करें

मैं आपके नियंत्रक को अनुवाद तर्क से मुक्त रखने की सलाह दूंगा और इस तरह अपने दृश्य के अंदर सीधे अपने तारों का अनुवाद करूंगा:

<h1>{{ 'TITLE.HELLO_WORLD' | translate }}</h1>

प्रदान की गई सेवा का उपयोग करना

कोणीय अनुवाद $translate सेवा प्रदान करता है जिसे आप अपने नियंत्रकों में उपयोग कर सकते हैं।

$translate सेवा का एक उदाहरण उपयोग हो सकता है:

.controller('TranslateMe', ['$scope', '$translate', function ($scope, $translate) {
    $translate('PAGE.TITLE')
        .then(function (translatedValue) {
            $scope.pageTitle = translatedValue;
        });
});

अनुवाद सेवा में $translate.instant() का उपयोग करके, वादे को संभालने की आवश्यकता के बिना तारों का सीधे अनुवाद करने का एक तरीका भी है:

.controller('TranslateMe', ['$scope', '$translate', function ($scope, $translate) {
    $scope.pageTitle = $translate.instant('TITLE.DASHBOARD'); // Assuming TITLE.DASHBOARD is defined
});

$translate.instant() का उपयोग करने के साथ नकारात्मकता यह हो सकती है कि भाषा फ़ाइल तब तक लोड नहीं की गई है जब आप इसे एसिंक लोड कर रहे हों।

प्रदत्त फ़िल्टर का उपयोग करना

यह मेरा पसंदीदा तरीका है क्योंकि मुझे इस तरह के वादे को संभालने की ज़रूरत नहीं है। फ़िल्टर का आउटपुट सीधे एक स्कोप वैरिएबल पर सेट किया जा सकता है।

.controller('TranslateMe', ['$scope', '$filter', function ($scope, $filter) {
    var $translate = $filter('translate');

    $scope.pageTitle = $translate('TITLE.DASHBOARD'); // Assuming TITLE.DASHBOARD is defined
});

प्रदत्त निर्देश का उपयोग करना

चूंकि @ पास्कलप्रैच इस भयानक लाइब्रेरी का निर्माता है, इसलिए मैं उसकी सलाह के साथ जाने की सिफारिश करता हूं (नीचे उसका जवाब देखें) और प्रदान किए गए निर्देश का उपयोग करें जो अनुवादों को बहुत बुद्धिमानी से संभालता है।

निर्देश असीमित निष्पादन का ख्याल रखता है और यदि अनुवाद में कोई गतिशील मान नहीं है तो दायरे पर अनुवाद आईडी को अनचाहे करने के लिए पर्याप्त चालाक भी है।


असल में, आपको इसके बजाय ऐसी सामग्री के लिए अनुवाद निर्देश का उपयोग करना चाहिए।

<h1 translate="{{pageTitle}}"></h1>

निर्देश असीमित निष्पादन का ख्याल रखता है और यदि अनुवाद में कोई गतिशील मान नहीं है तो दायरे पर अनुवाद आईडी को अनचाहे करने के लिए पर्याप्त चालाक भी है।

हालांकि, अगर वहां कोई रास्ता नहीं है और आपको वास्तव में नियंत्रक में $translate सेवा का उपयोग करना है, तो आपको $translate.instant() साथ संयोजन में $rootScope का उपयोग करके $rootScope $translateChangeSuccess ईवेंट में कॉल को लपेटना चाहिए:

.controller('foo', function ($rootScope, $scope, $translate) {
  $rootScope.$on('$translateChangeSuccess', function () {
    $scope.pageTitle = $translate.instant('PAGE.TITLE');
  });
})

तो क्यों $rootScope और $scope नहीं? इसका कारण यह है कि, कोणीय-अनुवाद की घटनाओं में $scope पर $scope $broadcast बजाय $rootScope पर $rootScope ed है, क्योंकि हमें पूरे दायरे पदानुक्रम के माध्यम से प्रसारित करने की आवश्यकता नहीं है।

क्यों $translate.instant() और async $translate() ? जब $translateChangeSuccess ईवेंट निकाल दिया जाता है, तो यह सुनिश्चित होता है कि आवश्यक अनुवाद डेटा वहां है और कोई असीमित निष्पादन नहीं हो रहा है (उदाहरण के लिए एसिंक्रोनस लोडर निष्पादन), इसलिए हम केवल $translate.instant() उपयोग कर सकते हैं जो तुल्यकालिक है और केवल उस अनुवाद को मानता है उपलब्ध हैं।

संस्करण 2.8.0 के बाद से $translate.onReady() , जो एक वादा देता है जैसे ही अनुवाद तैयार हो जाते हैं। चेंजलॉग देखें


नियंत्रक में अनुवाद करने के लिए आप $translate सेवा का उपयोग कर सकते हैं:

$translate(['COMMON.SI', 'COMMON.NO']).then(function (translations) {
    vm.si = translations['COMMON.SI'];
    vm.no = translations['COMMON.NO'];
});

यह कथन केवल नियंत्रक सक्रियण पर अनुवाद करता है लेकिन यह भाषा में रनटाइम परिवर्तन का पता नहीं लगाता है। उस व्यवहार को प्राप्त करने के लिए, आप $rootScope ईवेंट सुन सकते हैं: $translateChangeSuccess और वही अनुवाद करें:

    $rootScope.$on('$translateChangeSuccess', function () {
        $translate(['COMMON.SI', 'COMMON.NO']).then(function (translations) {
            vm.si = translations['COMMON.SI'];
            vm.no = translations['COMMON.NO'];
        });
    });

बेशक, आप एक विधि में $translate सेवा को समाहित कर सकते हैं और इसे नियंत्रक में और $translateChangeSucess श्रोता में कॉल कर सकते हैं।


संपादित करें : बेहतर समाधान के लिए कृपया पास्कलप्रैच (कोणीय-अनुवाद के लेखक) से उत्तर देखें।

लोडिंग की असीमित प्रकृति समस्या का कारण बनती है। आप {{ pageTitle | translate }} साथ देखते हैं {{ pageTitle | translate }} , कोणीय अभिव्यक्ति देखेंगे; जब स्थानीयकरण डेटा लोड होता है, अभिव्यक्ति का मान बदलता है और स्क्रीन अपडेट होती है।

तो, आप इसे स्वयं कर सकते हैं:

.controller('FirstPageCtrl', ['$scope', '$filter', function ($scope, $filter) {
    $scope.$watch(
        function() { return $filter('translate')('HELLO_WORLD'); },
        function(newval) { $scope.pageTitle = newval; }
    );
});

हालांकि, यह प्रत्येक पाचन चक्र पर देखे गए अभिव्यक्ति को चलाएगा। यह उप-स्थानिक है और दृश्य प्रदर्शन गिरावट का कारण हो सकता है या नहीं। वैसे भी यह कोणीय करता है, तो यह बुरा नहीं हो सकता है ...





angular-translate