কীভাবে টাইপস্ক্রিপ্ট ডেকোরেটর বাস্তবায়ন করবেন?


207

টাইপ করা বিষয় 1.5 এখন টেকনিক

কেউ কি কোনও সাজসজ্জার প্রয়োগের যথাযথ উপায় প্রদর্শনের একটি সহজ উদাহরণ প্রদান করতে পারেন এবং সম্ভাব্য বৈধ সাজসজ্জার স্বাক্ষরগুলিতে যুক্তিগুলির অর্থ কী তা বর্ণনা করতে পারে?

declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Function, propertyKey: string | symbol, parameterIndex: number) => void;

অতিরিক্তভাবে, কোনও সজ্জনকারী বাস্তবায়ন করার সময় কি এমন সর্বোত্তম অনুশীলনের বিবেচনাগুলি মনে রাখা উচিত?


নিজেকে নোট :-) যদি আপনি একটি উদ্বুদ্ধ করতে চান @Injectableএকটি প্রসাধক অনুবাদ করে, এবং পড়ুন
আনন্দ Rockzz

আমি এই প্রকল্পের যে একাধিক উদাহরণগুলি একবার দেখে নেওয়ার পরামর্শ দেব। একাধিক সজ্জকার রয়েছে - কিছু খুব সহজ এবং কিছু বুঝতে আরও জটিল হতে পারে: github.com/vlio20/utils-decorators
vlio20

উত্তর:


396

আমি সজ্জকারদের সাথে ঘুরেফিরে খেলা শেষ করেছি এবং যে কোনও ডকুমেন্টেশন প্রকাশের আগে এই সুবিধাটি নিতে চাইলে যে কারও জন্য আমি কী খুঁজে পেয়েছি তা নথিভুক্ত করার সিদ্ধান্ত নিয়েছি। আপনি যদি কোনও ভুল দেখতে পান তবে নির্দ্বিধায় এটিকে সম্পাদনা করুন।

জেনারেল পয়েন্টস

  • শ্রেণি ঘোষণার সময় সজ্জাকারীদের ডাকা হয় an যখন কোনও বস্তু তাত্ক্ষণিক হয় না।
  • একাধিক সজ্জাকারক একই শ্রেণি / সম্পত্তি / পদ্ধতি / পরামিতিতে সংজ্ঞায়িত করা যায়।
  • কনস্ট্রাক্টরগুলিতে সাজসজ্জার অনুমতি নেই।

একটি বৈধ সাজসজ্জা করা উচিত:

  1. সাজসজ্জারের এক ধরণের ( ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator) এর জন্য নির্ধারিত ।
  2. সজ্জিত মানকে বরাদ্দযোগ্য এমন কোনও মান (শ্রেণি সজ্জকার এবং পদ্ধতি সজ্জকারের ক্ষেত্রে) প্রদান করুন।

উল্লেখ


পদ্ধতি / ফর্মাল অ্যাকসেসর ডেকরেটার

বাস্তবায়ন পরামিতি:

  • target: ক্লাসের প্রোটোটাইপ ( Object)।
  • propertyKey: পদ্ধতির নাম ( string| symbol)।
  • descriptor: একটি TypedPropertyDescriptor- আপনি একটি বর্ণনাকারী এর কী এর মাধ্যমে অপরিচিত হন, তাহলে আমি এটা সম্পর্কে পড়ার পরামর্শ দেবেন এই ডকুমেন্টেশন উপর Object.defineProperty(এটা তৃতীয় প্যারামিটারটি এর)।

উদাহরণ - যুক্তি ছাড়াই

ব্যবহার করুন:

class MyClass {
    @log
    myMethod(arg: string) { 
        return "Message -- " + arg;
    }
}

বাস্তবায়ন:

function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
    const originalMethod = descriptor.value; // save a reference to the original method

    // NOTE: Do not use arrow syntax here. Use a function expression in 
    // order to use the correct value of `this` in this method (see notes below)
    descriptor.value = function(...args: any[]) {
        // pre
        console.log("The method args are: " + JSON.stringify(args));
        // run and store result
        const result = originalMethod.apply(this, args);
        // post
        console.log("The return value is: " + result);
        // return the result of the original method (or modify it before returning)
        return result;
    };

    return descriptor;
}

ইনপুট:

new MyClass().myMethod("testing");

আউটপুট:

পদ্ধতির আরগগুলি হ'ল: "" টেস্টিং "]

ফেরতের মানটি হ'ল: বার্তা - পরীক্ষা করা

মন্তব্য:

  • বর্ণনাকারীর মান নির্ধারণের সময় তীর সিনট্যাক্স ব্যবহার করবেন না। প্রসঙ্গটি thisযদি আপনি করেন তবে উদাহরণটি হবে না।
  • নতুন বর্ণনাকারীকে ফিরিয়ে দিয়ে বর্তমানের উপরের লিখনের চেয়ে মূল বর্ণনাকারীটিকে সংশোধন করা ভাল। এটি আপনাকে একাধিক সজ্জকার ব্যবহার করতে অনুমতি দেয় যা অন্য ডেকরেটারের কাজটি ওভাররাইট না করে বিবরণী সম্পাদনা করে। এইটি করলে আপনি ভালো কিছু ব্যবহার করার অনুমতি দেয় @enumerable(false)এবং @logএকই সময়ে (উদাহরণ: খারাপ বনাম গুড )
  • দরকারী : টাইপ আর্গুমেন্টটি TypedPropertyDescriptorকী পদ্ধতিতে স্বাক্ষরগুলি ( পদ্ধতির উদাহরণ ) বা অ্যাক্সেসরের স্বাক্ষরগুলি ( অ্যাকসেসরের উদাহরণ ) সজ্জা করতে হবে তা সীমাবদ্ধ করতে ব্যবহার করা যেতে পারে।

উদাহরণ - যুক্তি সহ (সজ্জা কারখানা)

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

class MyClass {
    @enumerable(false)
    get prop() {
        return true;
    }
}

function enumerable(isEnumerable: boolean) {
    return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
        descriptor.enumerable = isEnumerable;
        return descriptor;
    };
}

স্থিতিশীল পদ্ধতি সাজসজ্জা

কিছু পার্থক্য সহ একটি পদ্ধতি সাজসজ্জার অনুরূপ:

  • এর targetপ্যারামিটারটি নিজেই কনস্ট্রাক্টর ফাংশন এবং প্রোটোটাইপ নয়।
  • বর্ণনাকারী নির্ধারক কার্যক্রমে সংজ্ঞায়িত করা হয় প্রোটোটাইপ নয় ype

ক্লাস ডেকরেটার

@isTestable
class MyClass {}

বাস্তবায়ন পরামিতি:

  • target: শ্রেণি সাজসজ্জা ঘোষণা করা হয় ( TFunction extends Function)।

উদাহরণস্বরূপ ব্যবহার : ক্লাসে তথ্য সঞ্চয় করতে মেটাডেটা এপিআই ব্যবহার করা।


সম্পত্তি শোভাকর

class MyClass {
    @serialize
    name: string;
}

বাস্তবায়ন পরামিতি:

  • target: ক্লাসের প্রোটোটাইপ ( Object)।
  • propertyKey: সম্পত্তিটির নাম ( string| symbol)।

উদাহরণস্বরূপ ব্যবহার : একটি @serialize("serializedName")সাজসজ্জা তৈরি করা এবং বৈশিষ্ট্যটির তালিকাতে সম্পত্তিটির নাম যুক্ত করুন serial


প্যারামিটার ডেকোরেটর

class MyClass {
    myMethod(@myDecorator myParameter: string) {}
}

বাস্তবায়ন পরামিতি:

  • target: ক্লাসের প্রোটোটাইপ ( Functionএটি মনে Functionহয় আর কাজ করে না any যে কোনও শ্রেণীর মধ্যে ডেকরেটার ব্যবহার করতে আপনার এখন anyবা Objectএখানে ব্যবহার করা উচিত Or বা শ্রেণীর ধরণ (গুলি) নির্দিষ্ট করুন যা আপনি এটি সীমাবদ্ধ রাখতে চান)
  • propertyKey: পদ্ধতির নাম ( string| symbol)।
  • parameterIndex: ফাংশনটির পরামিতিগুলির তালিকাতে প্যারামিটারের সূচক ( number)।

সহজ উদাহরণ

বিস্তারিত উদাহরণ (গুলি)


আপনি কি জানেন যে কোথায় প্যারামিটার সজ্জাকারীর উদাহরণ পাবেন? আমি কোনও সাফল্য ছাড়াই
রেমো এইচ। জ্যানসেন

1
@ ওউআরআলোয়াডেডি আমি প্যারামিটার ডেকরেটারের অধীনে একটি উদাহরণ যুক্ত করেছি যা সজ্জাকারীকে কী পাস হয়েছে তা লগ আউট করে। আমি নিশ্চিত যদিও এটি সহায়ক কিনা। আমি এই মুহুর্তে একটি ভাল উদাহরণ সম্পর্কে ভাবতে পারি না।
ডেভিড শেরেট

এফওয়াইআই আমি গিথুবে
arolson101


আমি কি targetবা এর বিষয়ে কিছুটা বিভ্রান্ত হয়ে পড়েছি prototype of the classএবং এর মধ্যে keyকেউ কি দয়া করে বিস্তারিত বলতে পারেন?
সতেজ এস

8

একটি গুরুত্বপূর্ণ বিষয় যা আমি অন্য উত্তরে দেখি না:

সজ্জা কারখানা

যদি আমরা কীভাবে কোনও ডিকোরিয়রে কোনও ডিকোরেটার প্রয়োগ করা হয় তা কাস্টমাইজ করতে চাই, আমরা একটি ডেকরেটর কারখানা লিখতে পারি। একটি ডেকোরেটর কারখানা কেবল এমন একটি ফাংশন যা এক্সপ্রেশনটি ফিরিয়ে দেয় যা রানটাইম সময় ডেকোরেশন দ্বারা ডাকা হবে।

// This is a factory, returns one of ClassDecorator,
// PropertyDecorator, MethodDecorator, ParameterDecorator
function Entity(discriminator: string):  {
    return function(target) {
        // this is the decorator, in this case ClassDecorator.
    }
}

@Entity("cust")
export class MyCustomer { ... }

টাইপস্ক্রিপ্ট হ্যান্ডবুক সজ্জা অধ্যায়ে পরীক্ষা করুন ।


4
class Foo {
  @consoleLogger 
  Boo(name:string) { return "Hello, " + name }
}
  • লক্ষ্য: উপরের ক্ষেত্রে শ্রেণীর প্রোটোটাইপ এটি "ফু"
  • প্রপার্টি কে: উপরের ক্ষেত্রে "বু" পদ্ধতিটির নাম,
  • বর্ণনাকারী: অবজেক্টের বিবরণ => এর মান বৈশিষ্ট্য রয়েছে যা ফাংশনটি নিজেই: ফাংশন (নাম) {'হ্যালো' + নাম ফেরত দেয়; }

আপনি এমন কিছু বাস্তবায়ন করতে পারেন যা কনসোলে প্রতিটি কল লগ করে:

function consoleLogger(target: Function, key:string, value:any) 
{
  return value: (...args: any[]) => 
  {
     var a = args.map(a => JSON.stringify(a)).join();
     var result = value.value.apply(this, args);
     var r = JSON.stringify(result);

     console.log('called method' + key + ' with args ' + a + ' returned result ' + r);

     return result;
  }     
}

1
কঠোর সংকলক সেটিংস সংকলন করা এটির পক্ষে একটি কঠিন কাজ
পান্ডাওয়ুড

আসলে, এটি ভুল এবং সংকলন করতে পারে না, ফিরে আসার পরে সরাসরি কোঁকড়ানো ধনুর্বন্ধনী প্রয়োজন {মান: ...}। এটি আপনার কোডের একটি সম্ভাব্য উত্স থেকেও দেখা যাবে - blog.wolksoftware.com/…
পান্ডাওয়ুড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.