مطالب
قابلیت چند زبانه و Localization در AngularJs- بخش چهارم و نهایی: Best Practiceهای angular-translate
در بخش پیشین چند مورد از قابلیت‌های angular-translate را بررسی نمودیم. در این بخش به بررسی باقی موارد می‌پردازیم.

ex7_load_static_files 

در این مثال خواهیم دید که چگونه یک فایل translate table در موقع فراخوانی به صورت On Demand بارگذاری خواهد شد. در قدم اول اسکریپت‌های زیر به صفحه افزوده می‌شوند.
    <script src="Scripts/angular.js"></script>
    <script src="Scripts/angular-cookies.js"></script>
    <script src="Scripts/angular-translate.js"></script>
    <script src="Scripts/angular-translate-storage-cookie.js"></script>
    
    <!-- for override loader methods in angular translate -->
    <script src="/src/service/loader-static-files.js"></script>
در ادامه درباره‌ی اسکریپت پنجم بیشتر توضیح خواهیم داد. بگذارید از آخر به اول شروع کنیم و ببینیم که نحوه‌ی فراخوانی و استفاده از امکان on demand بارگذاری شدن فایل‌های زبان به چه صورتی می‌باشد. در زیر، تکه کد اصافه شده به ex7 را مشاهده می‌کنید:
            // Register a loader for the static files
            // So, the module will search missing translation tables under the specified urls.
            // Those urls are [prefix][langKey][suffix].
            $translateProvider.useStaticFilesLoader({
                prefix: '/l10n/',
                suffix: '.json'
            });
همانطور که در توضیحات آمده است، ماژول با دریافت prefix و suffix که در حقیقت همان فولدر و پسوند فایل‌های translate table هستند، هر زبانی را که مورد نیاز است و تا کنون بارگذاری نشده، بارگذاری می‌نماید. تصویر زیر محتویات فولدر l10n را نمایش می‌دهد.

حال ببینیم که این فرآیند در loader-static-files چگونه پیاده سازی شده است. در این فایل یک متد load نوشته شده است که فایل‌های static را طبق یک الگوی مشتمل بر prefix و suffix از سرور می‌خواند. لزومی ندارد که شما فایل‌ها را حتما به صورت JSON و با این پسوند ذخیره کنید. اما چیزی که قطعی است این است که فایل‌ها حتما باید به صورت key value ذخیره شده باشند.

تکه کد زیر اطلاعات فایل loader-static-files را نمایش می‌دهد.

angular.module('pascalprecht.translate')
.factory('$translateStaticFilesLoader', $translateStaticFilesLoader);
function $translateStaticFilesLoader($q, $http) {
    
  'use strict';

  return function (options) {

    if (!options || (!angular.isArray(options.files) && (!angular.isString(options.prefix) || !angular.isString(options.suffix)))) {
      throw new Error('Couldn\'t load static files, no files and prefix or suffix specified!');
    }

    if (!options.files) {
      options.files = [{
        prefix: options.prefix,
        suffix: options.suffix
      }];
    }

    var load = function (file) {
      if (!file || (!angular.isString(file.prefix) || !angular.isString(file.suffix))) {
        throw new Error('Couldn\'t load static file, no prefix or suffix specified!');
      }

      var deferred = $q.defer();

      $http(angular.extend({
        url: [
          file.prefix,
          options.key,
          file.suffix
        ].join(''),
        method: 'GET',
        params: ''
      }, options.$http)).success(function (data) {
        deferred.resolve(data);
      }).error(function () {
        deferred.reject(options.key);
      });

      return deferred.promise;
    };

    var deferred = $q.defer(),
        promises = [],
        length = options.files.length;

    for (var i = 0; i < length; i++) {
      promises.push(load({
        prefix: options.files[i].prefix,
        key: options.key,
        suffix: options.files[i].suffix
      }));
    }

    $q.all(promises).then(function (data) {
      var length = data.length,
          mergedData = {};

      for (var i = 0; i < length; i++) {
        for (var key in data[i]) {
          mergedData[key] = data[i][key];
        }
      }

      deferred.resolve(mergedData);
    }, function (data) {
      deferred.reject(data);
    });

    return deferred.promise;
  };
}

$translateStaticFilesLoader.displayName = '$translateStaticFilesLoader';

همانطور که ملاحظه می‌کنید، کد فوق یک سرویس با نام $translateStaticFilesLoader را تعریف نموده است. در صورتیکه ما در کنترلر فایل ex7، اصلا نامی از آن نبردیم و تنها از $translateProvider.useStaticFilesLoader استفاده نمودیم! جواب در نحوه‌ی نگارش کد angular-translate نهفته است. در خط 866 فایل angular-translate تکه کد زیر مربوط به تعریف translateStaticFileLoader می‌باشد. همانطور که ملاحظه می‌کنید سرویس translateStaticFilesLoader درون فضای نام سرویس translateTable قرار گرفته است. بنابراین ما تنها با تعریف سرویس translateStaticFilesLoader، در حقیقت آن را override نموده‌ایم. در کد نمونه‌ای که در بخش‌های قبلی قرار داده‌ام یک فایل translate.js نیز قرار دارد که در فولدر src/services قرار گرفته است. این فایل نیز برخی از امکانات و سرویس‌های built-in درون angular-translate را سفارشی نموده است.

  /**
   * @ngdoc function
   * @name pascalprecht.translate.$translateProvider#useStaticFilesLoader
   * @methodOf pascalprecht.translate.$translateProvider
   *
   * @description
   * Tells angular-translate to use `$translateStaticFilesLoader` extension service as loader.
   *
   * @param {Object=} options Optional configuration object
   */
  this.useStaticFilesLoader = function (options) {
    return this.useLoader('$translateStaticFilesLoader', options);
  };

در این 4 مجموعه سعی کردم تمامی آنچه را که برای ایجاد قابلیت چند زبانه و localization نیاز است و حیاتی بود، تشریح کنم. بنابراین تا کنون دانش خوبی درباره‌ی این کتابخانه کسب نموده‌اید. باقی تمرین‌ها را می‌توانید بر حسب نیاز با استفاده از مستندات موجود در angular-translate مطالعه و استفاده نمایید.

اشتراک‌ها
سری React مدرن

Full Modern React Tutorial
32 videos
In this full React tutorial series, I'll take you from novice to ninja. We'll cover all the basics - what React is, setting up, components & routing - before diving into state management, async code, built-in hooks & custom hooks too. 

سری React مدرن
اشتراک‌ها
دوره 7 ساعته Docker

Docker Full Course - Learn Docker in 7 Hours [2023] | Docker Tutorial For Beginners

This will help you understand and learn docker in detail. This Docker tutorial is ideal for both beginners as well as professionals who want to master the container concepts.
 

دوره 7 ساعته Docker
اشتراک‌ها
سری آموزشی 150 قسمتی کار با SQL Server

SQL Server tutorial for beginners
150 videos
In this tutorial, we will start from the very basics and cover topics like joins, views, triggers, system functions, stored procedures, user defined scalar and table valued functions etc. These video tutorials will be useful for frehsers, experienced .NET and SQL Database developers.  

سری آموزشی 150 قسمتی کار با SQL Server
اشتراک‌ها
مصاحبه کامل با خالق ++C

Full Interview With the Creator of C++

By popular demand, and a request from the man himself, we’ve decided to release the full interview with esteemed computer scientist Bjarne Stroustrup (aka the creator of C++). We cover a bunch of topics so check the chapters to find what interests you the most! Filmed last year. Enjoy and happy trails!

00:00-02:42 Getting into programming
02:42-03:26 Programming being versatile
03:26-06:07 Industry changes
06:07-10:20 Inventing and maintaining C++
10:20-12:02 Key to making a successful language
12:02-16:04 Greatest lessons
16:14-20:06 Moving to the US
20:06-23:20 Advice to devs 

مصاحبه کامل با خالق ++C
نظرات مطالب
کنترل دسترسی‌ها در Angular با استفاده از Ng2Permission
بعد از نصب و معرفی آن در appmodule برنامه ،  پیغام زیر درCommand Prompt نمایش می‌دهد. آیا این پکیج همخوانی با Angular 5 ندارد؟
ERROR in ./node_modules/angular2-permission/index.ts
Module build failed: Error: C:\Front\node_modules\angular2-permission\index.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.
The missing file seems to be part of a third party library. TS files in published libraries are often a sign of a badly packaged library. Please open an issue in the library repository to alert its author and ask them to package the library using the Angular Package Format (https://goo.gl/jB3GVv).
    at AngularCompilerPlugin.getCompiledFile (C:\Front\node_modules\@ngtools\webpack\src\angular_compiler_plugin.js:674:23)
    at plugin.done.then (C:\Front\node_modules\@ngtools\webpack\src\loader.js:467:39)
    at process._tickCallback (internal/process/next_tick.js:68:7)

مطالب
C# 7.1 - Tuple Name Inference
در مطلب «C# 7 - Tuple return types and deconstruction» با نوع‌های جدید بازگشتی Tuple در C# 7.0 آشنا شدیم. در C# 7.1 تشخیص نام اعضای Tuple تعریف شده بهبود یافته و از این لحاظ شبیه به anonymous types شده‌است. مفهوم «Name Inference» یا «حدس زدن نام‌ها» را با یک مثال بهتر می‌توان توضیح داد.
string name = "User 1";
int age = 20;
var personTuple = (name, age);
Console.WriteLine(personTuple.Item1); // User 1
Console.WriteLine(personTuple.Item2); // 20
در C# 7.0 مفهوم «Name Inference» پیاده سازی نشده‌است. به همین جهت کامپایلر قادر نیست نام اعضای Tuple تعریف شده‌ی فوق را حدس بزند و برای دسترسی به آن‌ها باید تنها از Item1 و Item2 مانند قبل استفاده کرد. البته اگر برای اعضای Tuple نام تعریف کنیم (قسمت «مفهوم Tuple Literals»)، آنگاه می‌توان Item1 و Item2 را با نام‌های این اعضاء جایگزین کرد:
string name = "User 1";
int age = 20;
var personTuple = (name: name, age:age);
Console.WriteLine(personTuple.name); // User 1
Console.WriteLine(personTuple.age); // 20
بنابراین ذکر نام صریح اعضای Tuple در سی‌شارپ 7 الزامی است؛ در غیراینصورت باید با همان نام‌های عمومی Item1 و Item2 جهت دسترسی به این اعضاء، کار کرد.
این وضعیت در C# 7.1 بهبود یافته‌است و اکنون کامپایلر در صورت عدم ذکر صریح نام اعضای Tuple، قادر است این نام‌ها را دقیقا بر اساس نام متغیرها، همانند قابلیتی که در مورد anonymous types وجود دارد، تعیین کند و حدس بزند:
string name = "User 1";
int age = 20;
var personTuple = (name, age);
Console.WriteLine(personTuple.name); // User 1
Console.WriteLine(personTuple.age); // 20
این مثال، شبیه به اولین مثالی است که در مورد C# 7.0 ذکر شد. اما در C# 7.1 نیازی به ذکر Item1 و Item2 جهت دسترسی به اعضای Tuple تعریف شده نیست (هرچند هنوز هم مجاز است) و کامپایلر نام این اعضاء را از نام متغیرهای متناظر با آن‌ها حدس می‌زند.


مثال‌هایی از حدس زدن نام‌های اعضای Tuple در C# 7.1

مثال اول همان حدس زدن نام‌های اعضای Tuple بر اساس نام متغیرهای محلی متناظر با آن‌ها است.

مثال دوم بر اساس نام خواص یک شیء است که توسط یک نوع Tuple بازگشت داده می‌شود:
var p = new Person
{
   Name = "User 1",
   Age = 20
};
var personTuple = (p.Name, p.Age);
Console.WriteLine(personTuple.Name);
Console.WriteLine(personTuple.Age);

در اینجا عملگر .? نیز پشتیبانی می‌شود:
Person p = null;
var personTuple = (p?.Name, p?.Age);
Console.WriteLine(personTuple.Name); // null
Console.WriteLine(personTuple.Age); // null

مثال سوم همان مثال دوم است که در یک عبارت LINQ بکار رفته‌است:
var people = new List<Person>
{
   new Person {Name = "User 1", Age = 42},
   new Person {Name = "User 2", Age = 18},
   new Person {Name = "User 3", Age = 21}
};

var tuples = people
   .Select(person =>
           (
              person.Name,
              person.Age,
              NameAndAge: $"{person.Name} is {person.Age}"
           )
);
var name = tuples.First().Name;
var age = tuples.First().Age; 
var nameAndAge = tuples.First().NameAndAge;
در اینجا نوع خروجی عبارت LINQ نوشته شده، لیستی از Tupleها است. در Tuple خروجی آن، نام دو عضو اول، از نام خواص متناظر با آن‌ها حدس زده می‌شود. نام عنصر سوم به صورت صریح مشخص شده‌است.


نکته 1: حدس زدن نام‌ها در مورد مقادیر خروجی متدها رخ نمی‌دهد.

در مثال ذیل نمی‌توان به personTuple.FirstName بر اساس نام متد ذکر شده دسترسی یافت و تنها می‌توان از Item1 در مورد آن استفاده کرد؛ اما در مورد متغیر محلی age می‌توان:
int age = 42;
var personTuple = (FirstName(), age);
Console.WriteLine(personTuple.Item1);
Console.WriteLine(personTuple.age);


نکته 2: اگر نام اعضای Tuple یکی باشند، عملیات حدس زدن نام‌ها رخ نمی‌دهد.

var p1 = new Person
{
   Name = "User 1",
   Age = 20
};

var p2 = new Person
{
   Name = "User 2",
   Age = 22
};

var personTuple = (p1.Name, p2.Name);
Console.WriteLine(personTuple.Item1); // User 1
Console.WriteLine(personTuple.Item2); // User 2
در این مثال چون Tuple تشکیل شده دارای نام‌های یکسان Name است، امکان حدس زدن نام‌ها میسر نیست و در اینجا نیز باید از طریق Item1 و ... به اعضای Tuple دسترسی یافت (و یا می‌توان به هر عضو Tuple یک نام منحصربفرد را انتساب داد).
اشتراک‌ها
تفاوت اعتبارسنجی ورودی ها با اعتبارسنجی مرتبط با قواعد تجاری

Input Validation for me is about validating the user input. Some people call "Name must not be empty" a business rule, I think about it as input validation. Business Rules validation is more complex, because a business rule for me is not "Name must not be empty", it is a definition of a state in the system that requires an action. Here is a definition of a business rule:

An order should be payed within 30 days, this duration can be extended, to a maximum of three times. 

تفاوت اعتبارسنجی ورودی ها با اعتبارسنجی مرتبط با قواعد تجاری
نظرات مطالب
EF Code First #15
- امکان «استفاده مستقیم از عبارات SQL در EF Code first » وجود دارد؛ برای تمام حالاتی که EF آن‌ها را به صورت توکار پشتیبانی نمی‌کند.
- محل قرار دادن تنظیمات مقدماتی از این دست، در متد Seed مهاجرت هست. یک مثال و مثالی دیگر در مورد کار با Seed.
نظرات مطالب
آموزش VC++ از مقدماتی تا پیشرفته
انشاا... قسمت باشه حتما صحبت میکنیم ، ولی اگر به تیتر موضوع دقت کنید هدف آموزش از مقدماتی تا پیشرفته است که اگر خدا یاری کند ادامه میدم و در خدمت اساتید و دوستان خواهم بود .
در مورد مبحثی که شما فرمودین در اینجا کامل توضیح داده شده است .
مباحث جدید حتما جزئی از آموزش خواهند بود .