নিয়ামকগুলিতে কৌণিক-অনুবাদের জন্য সঠিক ব্যবহার


121

আমি AngularJS অ্যাপ্লিকেশনে i18n এর জন্য কৌণিক-অনুবাদ ব্যবহার করছি ।

প্রতিটি অ্যাপ্লিকেশন দেখার জন্য, একটি ডেডিকেটেড নিয়ামক রয়েছে। নীচের কন্ট্রোলারে, আমি পৃষ্ঠা শিরোনাম হিসাবে প্রদর্শিত হবে মান সেট।

কোড

এইচটিএমএল

<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';
    }])

আমি কৌণিক-অনুবাদ-লোডার-ইউআরএল এক্সটেনশানটি ব্যবহার করে অনুবাদ ফাইলগুলি লোড করছি ।

সমস্যা

প্রাথমিক পৃষ্ঠা লোডে অনুবাদ কীটি সেই কীটির জন্য অনুবাদটির পরিবর্তে প্রদর্শিত হবে। অনুবাদটি হচ্ছে Hello, World!, তবে আমি দেখছি HELLO_WORLD

দ্বিতীয়বার আমি পৃষ্ঠায় যাচ্ছি, সবকিছু ঠিক আছে এবং অনুবাদকৃত সংস্করণটি প্রদর্শিত হবে।

আমি ধরে নিয়েছি যে বিষয়টি নিয়মের সাথে মান নির্ধারণের সময় অনুবাদ ফাইলটি এখনও লোড হয়নি এমনটি এই বিষয়টিটির সাথে সম্পর্কিত $scope.pageTitle

মন্তব্য

ব্যবহার <h1>{{ pageTitle | translate }}</h1>এবং করার সময় $scope.pageTitle = 'HELLO_WORLD';, অনুবাদটি প্রথমবার থেকে নিখুঁতভাবে কাজ করে। এর সাথে সমস্যাটি হ'ল আমি সবসময় অনুবাদ ব্যবহার করতে চাই না (যেমন দ্বিতীয় নিয়ামকের জন্য আমি কেবল একটি কাঁচা স্ট্রিং পাস করতে চাই)।

প্রশ্ন

এটি কি জ্ঞাত সমস্যা / সীমাবদ্ধতা? কিভাবে এই সমাধান করা যেতে পারে?

উত্তর:


69

সম্পাদনা : আরও ভাল সমাধানের জন্য দয়া করে পাস্কালপ্রিট (কৌণিক-অনুবাদ অনুবাদক) এর উত্তর দেখুন।


লোডিংয়ের অ্যাসিনক্রোনাস প্রকৃতি সমস্যা তৈরি করে। আপনি দেখুন, এর সাথে {{ pageTitle | translate }}কৌণিকটি অভিব্যক্তিটি দেখবে; স্থানীয়করণের ডেটা লোড হয়ে গেলে অভিব্যক্তির মান পরিবর্তন হয় এবং পর্দা আপডেট হয়।

সুতরাং, আপনি নিজে এটি করতে পারেন:

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

যাইহোক, এটি প্রতিটি ডাইজেস্ট চক্রের দেখা দর্শন প্রকাশ করবে। এটি সাবঅপটিমাল এবং এটি দৃশ্যমান পারফরম্যান্স অবক্ষয়ের কারণ হতে পারে বা নাও পারে। যাই হোক না কেন এটি কৌণিক যা করে তাই এটি খারাপ হতে পারে না ...


ধন্যবাদ! আমি আশা করব যে ভিউতে বা একটি নিয়ামকের মধ্যে একটি ফিল্টার ব্যবহার করা ঠিক একইরকম আচরণ করবে। এখানে বিষয়টি মনে হয় না।
ndequeker

আমি বলব যে $scope.$watchএটির ব্যবহারটি বরং ওভারকিল, যেহেতু কৌণিক অনুবাদ কন্ট্রোলারগুলিতে ব্যবহার করার জন্য একটি পরিষেবা সরবরাহ করছে। আমার উত্তর নীচে দেখুন।
রবিন ভ্যান বালেন

1
কৌণিক অনুবাদ ফিল্টার প্রয়োজন হয় না, যেহেতু $translate.instant()পরিষেবা হিসাবে একই অফার করে। এর পাশেই, দয়া করে পাস্কেলের উত্তরের দিকে মনোযোগ দিন।
knalli

আমি সম্মত, $ ঘড়ি ব্যবহার করা ওভারকিল। নীচে উত্তরগুলি আরও সঠিক ব্যবহার।
jpblancoder

141

প্রস্তাবিত: নিয়ামকটিতে অনুবাদ করবেন না, আপনার দৃষ্টিতে অনুবাদ করুন

আমি আপনার নিয়ামককে অনুবাদ যুক্তি থেকে মুক্ত রাখার এবং আপনার স্ট্রিংগুলি সরাসরি আপনার দর্শনের মধ্যে এমনভাবে অনুবাদ করার পরামর্শ দেব:

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

প্রদত্ত নির্দেশনা ব্যবহার করে

যেহেতু @ প্যাসালপ্রাচ্ট এই দুর্দান্ত লাইব্রেরির স্রষ্টা, তাই আমি তাঁর পরামর্শ নিয়ে যাওয়ার পরামর্শ দিই (নীচে তার উত্তর দেখুন) এবং প্রদত্ত নির্দেশনাটি ব্যবহার করব যা অনুবাদগুলি খুব বুদ্ধিমানভাবে পরিচালনা করে বলে মনে হচ্ছে।

এই নির্দেশনাটি অ্যাসিঙ্ক্রোনাস এক্সিকিউশনের যত্ন নেয় এবং অনুবাদটির কোনও গতিশীল মান না থাকলে স্কোলে অনুবাদ আইডিকে আনচচ করার পক্ষে যথেষ্ট চালাক।


যদি আপনি এই সম্পর্কহীন মন্তব্য লেখার পরিবর্তে চেষ্টা করে থাকেন তবে আপনি এখনই উত্তরটি জানতেন। সংক্ষিপ্ত উত্তর: হ্যাঁ সম্ভব।
রবিন ভ্যান বালেন

1
আপনার উদাহরণস্বরূপ নিয়ামকটিতে ফিল্টারটি রয়েছে: তাত্ক্ষণিক () এর মতো, যদি ভাষা ফাইলটি লোড না করা হয় তবে এটি ঠিক কাজ করবে না? আমরা কি এই ক্ষেত্রে একটি ঘড়ি ব্যবহার করা উচিত? অথবা আপনি বলতে চাইছেন যে অনুবাদগুলি লোড হয়েছে তবেই আপনি ফিল্টারটি ব্যবহার করুন?
বোম্বিনোশ

@ বোম্বিনোশ আমি যদি বলি যে অনুবাদগুলি লোড হয়েছে তবে ফিল্টার পদ্ধতিটি ব্যবহার করুন। ব্যক্তিগতভাবে আমি এমনকি আপনার প্রয়োজন না থাকলে ডায়নামিকভাবে অনুবাদগুলি লোড না করার পরামর্শ দেব। এটি আপনার আবেদনের একটি বাধ্যতামূলক অংশ, সুতরাং আপনি চান না যে ব্যবহারকারী এটির জন্য অপেক্ষা করুক। তবে এটি একটি ব্যক্তিগত মতামত।
রবিন ভ্যান বালেন

অনুবাদগুলির বিষয়টি হ'ল তারা ব্যবহারকারীর পছন্দ বা এমনকি ব্যবহারকারী ক্রিয়ায় পরিবর্তন করতে পারে। সুতরাং আপনার প্রয়োজন হয়, সাধারণভাবে এগুলি গতিশীলভাবে লোড করা। কমপক্ষে অনুবাদ করার জন্য স্ট্রিংয়ের সংখ্যাটি গুরুত্বপূর্ণ, এবং / অথবা যদি আপনার প্রচুর অনুবাদ থাকে।
ফিলিহো 10

4
এইচটিএমএলে অনুবাদটি করা হয়ে গেলে ডাইজেস্ট চক্রটি দু'বার চালানো হয় তবে নিয়ামকটিতে একবার চালানো হয়। 99% ক্ষেত্রে সম্ভবত এটি কোনও ব্যাপার নয় তবে আমার অনেক কক্ষে অনুবাদ সহ একটি কৌণিক ইউআই গ্রিডে ভয়ানক পারফরম্যান্স নিয়ে একটি সমস্যা হয়েছিল। নিশ্চিত হওয়ার জন্য একটি প্রান্তের কেস, সচেতন হওয়ার জন্য কেবল কিছু
tykowale

123

আসলে, আপনার পরিবর্তে এই জাতীয় সামগ্রীর জন্য অনুবাদ নির্দেশিকা ব্যবহার করা উচিত।

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

এই নির্দেশনাটি অ্যাসিঙ্ক্রোনাস এক্সিকিউশনের যত্ন নেয় এবং অনুবাদটির কোনও গতিশীল মান না থাকলে স্কোলে অনুবাদ আইডিকে আনচচ করার পক্ষে যথেষ্ট চালাক।

যাইহোক, প্রায় কোন উপায় এবং যদি সত্যিই আপনি যদি আছে ব্যবহার $translateনিয়ামক মধ্যে সেবা আপনি কি কলটি একটি মোড়ানো উচিত $translateChangeSuccessঘটনা ব্যবহার $rootScopeসঙ্গে একযোগে $translate.instant()এই মত:

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

তাহলে আর কেন $rootScopeনয় $scope? এর কারণটি হ'ল, কৌণিক অনুবাদে ইভেন্টগুলি $emitএড করার $rootScopeপরিবর্তে $broadcastএড হয়$scope কারণ আমাদের পুরো স্কোপ শ্রেণিবিন্যাসের মাধ্যমে সম্প্রচারের দরকার নেই।

কেন $translate.instant()এবং শুধু async না $translate()? যখন $translateChangeSuccessইভেন্টটি বরখাস্ত করা হয়, তখন এটি নিশ্চিত হয়ে যায় যে প্রয়োজনীয় অনুবাদ ডেটা আছে এবং কোনও অ্যাসিনক্রোনাস এক্সিকিউশন হচ্ছে না (উদাহরণস্বরূপ অ্যাসিনক্রোনাস লোডার এক্সিকিউশন), সুতরাং আমরা কেবল ব্যবহার করতে পারি$translate.instant() যা সিঙ্ক্রোনাস এবং কেবল ধরে নেওয়া যায় যে অনুবাদগুলি উপলভ্য।

সংস্করণ ২.৮.০ থেকে এটিও রয়েছে $translate.onReady(), যা একটি প্রতিশ্রুতি দেয় যা অনুবাদগুলি প্রস্তুত হওয়ার সাথে সাথেই সমাধান হয়ে যায়। চেঞ্জলগটি দেখুন


আমি যদি ফিল্টারের পরিবর্তে অনুবাদ নির্দেশিকা ব্যবহার করি তবে কোনও কার্য সম্পাদনের সমস্যা থাকতে পারে? এছাড়াও আমি অভ্যন্তরীণভাবে বিশ্বাস করি, এটি তাত্ক্ষণিক () এর রিটার্ন মান দেখে। সুতরাং যখন বর্তমান সুযোগটি নষ্ট হয়ে যায় তখন এটি কি ঘড়িগুলি সরিয়ে দেয়?
নিলেশ

আমি আপনার পরামর্শটি ব্যবহার করার চেষ্টা করেছি তবে স্কোপ ভেরিয়েবলের মান পরিবর্তনশীল হলে এটি কার্যকর হয় না।
নিলেশ

10
প্রকৃতপক্ষে ফিল্টারগুলি এড়ানো ভাল always কারণ এটি আপনার অ্যাপ্লিকেশনটিকে ধীর করে দেয় কারণ তারা সর্বদা নতুন ঘড়ি সেটআপ করে। নির্দেশনাটি অবশ্য খানিকটা এগিয়ে যায়। এটি কোনও অনুবাদ আইডির মান দেখতে হবে কিনা তা পরীক্ষা করে। এটি আপনার অ্যাপ্লিকেশনটিকে আরও ভালভাবে সম্পাদন করতে দেয়। আপনি কি একটি নিমজ্জন তৈরি করতে এবং আমাকে এর সাথে লিঙ্ক করতে পারেন, যাতে আমি আরও একবার নজর দিতে পারি?
পাস্কাল প্রেচট

প্লাঙ্ক: plnkr.co/edit/j53xL1EdJ6bT20ldlhxr সম্ভবত আমার উদাহরণে, নির্দেশটি মান না দেখার সিদ্ধান্ত নিচ্ছে । পৃথক সমস্যা হিসাবে, কী না পাওয়া গেলে আমার কাস্টম ত্রুটি হ্যান্ডলারটি কল হয়ে যায় তবে এটি ফেরত স্ট্রিংটি প্রদর্শন করে না। আমি এর জন্য আরও একটি নিমজ্জন করব।
নিলেশ

2
@ প্যাসালপ্রাচ্ট শুধু একটি প্রশ্ন, অনুবাদ করে বাইন্ড একবার ব্যবহার করা কি ভাল অভ্যাস? এই মত {{::'HELLO_WORLD | translate}}'
জুনিয়র জুবায়ের

5

নিয়ামকটিতে একটি অনুবাদ করতে আপনি $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শ্রোতার কাছে কল করতে পারেন ।


1

যা হচ্ছে তা হ'ল অ্যাঙ্গুলার-ট্রান্সলেটটি ইভেন্ট-ভিত্তিক সিস্টেমের সাথে এক্সপ্রেশনটি দেখছে এবং ঠিক যেমন বাইন্ডিং বা দ্বি-মুখী বাইন্ডিংয়ের অন্য কোনও ক্ষেত্রে, ডেটা পুনরুদ্ধার করার সময় একটি ইভেন্ট বরখাস্ত করা হয়, এবং মানটি পরিবর্তিত হয়, যা স্পষ্টতই অনুবাদ জন্য কাজ করে না। পৃষ্ঠার অন্যান্য গতিশীল ডেটা থেকে আলাদা অনুবাদ ডেটা অবশ্যই অবশ্যই ব্যবহারকারীর সামনে উপস্থিত হতে হবে। পৃষ্ঠা লোড হওয়ার পরে এটি পপ ইন করতে পারে না।

এমনকি আপনি যদি এই সমস্যাটি সফলভাবে ডিবাগ করতে পারেন তবে বড় সমস্যাটি হ'ল জড়িত উন্নয়ন কাজগুলি বিশাল। একজন বিকাশকারীকে ম্যানুয়ালি সাইটে প্রতিটি স্ট্রিং বের করতে হয়, এটিকে একটি জেএসএন ফাইলে রেখে স্ট্রিং কোডের মাধ্যমে ম্যানুয়ালি রেফারেন্স করতে হয় (অর্থাত্ এই ক্ষেত্রে 'পেজটাইটেল')। বেশিরভাগ বাণিজ্যিক সাইটে হাজার হাজার স্ট্রিং রয়েছে যার জন্য এটি হওয়া দরকার। এবং এটি ঠিক শুরু। আপনার এখন অনুবাদগুলি সিঙ্কে রাখার একটি সিস্টেমের দরকার যখন তাদের মধ্যে কিছুটির অন্তর্নিহিত পাঠ্য পরিবর্তিত হয়, অনুবাদ ফাইলগুলি বিভিন্ন অনুবাদকের কাছে পাঠানোর জন্য, সেগুলি পুনর্নির্মাণের জন্য, সাইটটিকে পুনরায় প্রবর্তনের, যাতে অনুবাদকরা দেখতে পান প্রসঙ্গে এবং তাদের পরিবর্তনগুলি।

এছাড়াও, এটি একটি 'বাধ্যবাধকতা', ইভেন্ট-ভিত্তিক সিস্টেম হিসাবে, পৃষ্ঠাটির প্রতিটি একক স্ট্রিংয়ের জন্য একটি ইভেন্ট নিক্ষেপ করা হচ্ছে যা কেবল পৃষ্ঠাটি রূপান্তর করার জন্য একটি ধীর পথ নয়, তবে পৃষ্ঠার সমস্ত ক্রিয়াকে ধীর করতে পারে, যদি আপনি এটিতে বিশাল সংখ্যক ইভেন্ট যুক্ত করতে শুরু করেন।

যাইহোক, পোস্ট-প্রসেসিং অনুবাদ প্ল্যাটফর্মটি ব্যবহার করা আমার কাছে আরও অর্থবোধ করে। গ্লোবালাইজআইটি উদাহরণস্বরূপ, কোনও অনুবাদক কেবল সাইটের কোনও পৃষ্ঠায় যেতে পারেন এবং তাদের ভাষার জন্য সরাসরি পৃষ্ঠায় পাঠ্য সম্পাদনা শুরু করতে পারেন এবং এটি হ'ল : https://www.globalizeit.com/HowItWorks । কোনও প্রোগ্রামিংয়ের প্রয়োজন নেই (যদিও এটি প্রোগ্রামিক্যালি এক্সটেনসিবল হতে পারে), এটি কৌণিকের সাথে সহজেই সংহত করে: https://www.globalizeit.com/Translate/Angular , পৃষ্ঠার রূপান্তর এক সাথে হয়, এবং এটি সর্বদা এর সাথে অনুবাদকৃত পাঠ্যটি প্রদর্শন করে পৃষ্ঠার প্রাথমিক রেন্ডার।

সম্পূর্ণ প্রকাশ: আমি একজন সহ-প্রতিষ্ঠাতা :)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.