घटकों को कैसे बढ़ाया / विरासत में दिया जाए?


160

मैं पहले से ही लगभग पूरी तरह से उन्हें फिर से लिखने के बिना, कोणीय 2 में पहले से ही तैनात कुछ घटकों के लिए एक्सटेंशन बनाना चाहूंगा, क्योंकि आधार घटक परिवर्तनों से गुजर सकता है और काश ये परिवर्तन इसके व्युत्पन्न घटकों में भी परिलक्षित होते।

मैंने अपने प्रश्नों को बेहतर ढंग से समझाने की कोशिश करने के लिए यह सरल उदाहरण बनाया:

निम्नलिखित आधार घटक के साथ app/base-panel.component.ts:

import {Component, Input} from 'angular2/core';

@Component({
    selector: 'base-panel',
    template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
    styles: [`
    .panel{
    padding: 50px;
  }
  `]
})
export class BasePanelComponent { 

  @Input() content: string;

  color: string = "red";

  onClick(event){
    console.log("Click color: " + this.color);
  }
}

क्या आप केवल एक और व्युत्पन्न घटक बनाना चाहेंगे, उदाहरण के लिए, रंग के मामले में एक बुनियादी घटक व्यवहार app/my-panel.component.ts:

import {Component} from 'angular2/core';
import {BasePanelComponent} from './base-panel.component'

@Component({
    selector: 'my-panel',
    template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
    styles: [`
    .panel{
    padding: 50px;
  }
  `]
})
export class MyPanelComponent extends BasePanelComponent{

  constructor() {
    super();
    this.color = "blue";
  }
}

प्लंकर में काम करने का पूरा उदाहरण

नोट: स्पष्ट रूप से यह उदाहरण सरल है और इसे हल किया जा सकता है अन्यथा इनहेरिटेंस का उपयोग करने की कोई आवश्यकता नहीं है, लेकिन इसका उद्देश्य केवल वास्तविक समस्या का वर्णन करना है।

जैसा कि आप व्युत्पन्न घटक के कार्यान्वयन में देख सकते हैं app/my-panel.component.ts, बहुत अधिक कार्यान्वयन दोहराया गया था, और वास्तव में विरासत में मिला एकल भाग था class BasePanelComponent, लेकिन कार्यान्वयन के @Componentरूप में मूल रूप से पूरी तरह से दोहराया जाना चाहिए, न कि केवल बदले हुए हिस्से selector: 'my-panel'

क्या एक घटक Angular2 की शाब्दिक पूर्ण विरासत बनाने का कोई तरीका है class, उदाहरण के लिए चिह्नों / टिप्पणियों की परिभाषा विरासत में मिली है @Component?

संपादित 1 - फ़ीचर अनुरोध

GitHub पर प्रोजेक्ट में फ़ीचर अनुरोध कोणीय 2 जोड़ा गया: विस्तार / Inherit कोणीय 2 घटक एनोटेशन # 7968

2 संपादित करें - बंद अनुरोध

अनुरोध बंद कर दिया गया था, इस कारण से , संक्षेप में पता नहीं होगा कि डेकोरेटर को कैसे मर्ज किया जाएगा। हमें कोई विकल्प नहीं छोड़कर। इसलिए मेरी राय अंक में उद्धृत की गई है


इस उत्तर की जाँच करें stackoverflow.com/questions/36063627/… सादर
निकोलस

ठीक है निकोलस। लेकिन मेरी समस्या डेकोरेटर @Component की विरासत के साथ है, जो विरासत मेटाडेटा पर लागू नहीं होती है। = /
फर्नांडो लील

लोग, कृपया कोणीय के साथ विरासत के उपयोग से बचें। जैसे निर्यात वर्ग PlannedFilterComponent का विस्तार करता है AbstractFilterComponent लागू करता है OnInit {बहुत खराब है। कोड को साझा करने के अन्य तरीके हैं जैसे सेवाएं और छोटे घटक। वंशानुक्रम कोणीय तरीका नहीं है। मैं एक कोणीय परियोजना पर हूं जहां उन्होंने विरासत का उपयोग किया है और ऐसी चीजें हैं जो ऐसे निर्यात घटकों के रूप में हैं जो सार घटकों से विरासत में मिली हैं जो सार वर्ग के इनपुट लापता हैं।
रोबर्ट राजा

1
इसके बजाय सामग्री के प्रक्षेपण का उपयोग करें जैसे github.com/angular/comports/blob/master/src/material/card/… इनहेरिटेंस का उपयोग न करें
robert

जवाबों:


39

दूसरा तरीका:

Thierry Templier का यह उत्तर समस्या के आसपास जाने का एक वैकल्पिक तरीका है।

थियरी टेम्पलर के साथ कुछ सवालों के बाद, मैं निम्नलिखित कार्य उदाहरण के लिए आया हूं जो इस प्रश्न में उल्लिखित विरासत सीमा के विकल्प के रूप में मेरी अपेक्षाओं को पूरा करता है:

1 - कस्टम डेकोरेटर बनाएँ:

export function CustomComponent(annotation: any) {
  return function (target: Function) {
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);

    var parentAnnotation = parentAnnotations[0];
    Object.keys(parentAnnotation).forEach(key => {
      if (isPresent(parentAnnotation[key])) {
        // verify is annotation typeof function
        if(typeof annotation[key] === 'function'){
          annotation[key] = annotation[key].call(this, parentAnnotation[key]);
        }else if(
        // force override in annotation base
        !isPresent(annotation[key])
        ){
          annotation[key] = parentAnnotation[key];
        }
      }
    });

    var metadata = new Component(annotation);

    Reflect.defineMetadata('annotations', [ metadata ], target);
  }
}

2 - @ कॉम्पोनेंट डेकोरेटर के साथ बेस कंपोनेंट:

@Component({
  // create seletor base for test override property
  selector: 'master',
  template: `
    <div>Test</div>
  `
})
export class AbstractComponent {

}

3 - उप घटक @CustomComponent डेकोरेटर के साथ:

@CustomComponent({
  // override property annotation
  //selector: 'sub',
  selector: (parentSelector) => { return parentSelector + 'sub'}
})
export class SubComponent extends AbstractComponent {
  constructor() {
  }
}

पूर्ण उदाहरण के साथ प्लंकर।


3
मुझे लगता है कि यह ऑफ़लाइन टेम्पलेट कंपाइलर के साथ संगत नहीं होगा।
गुंटर ज़ोचाउर

@ GünterZöchbauer, मुझे Angular2 के "ऑफ़लाइन संकलक टेम्पलेट" के बारे में कोई जानकारी नहीं है। लेकिन मुझे लगता है कि यह संगत नहीं हो सकता है, और यह एक वैकल्पिक विकल्प होगा। Angular2 का मोड "ऑफ़लाइन टेम्पलेट कंपाइलर" कहां उपयोगी होगा? इस बारे में बेहतर समझने के लिए आप मुझे कुछ दिखा सकते हैं? इसलिए मैं अपनी परियोजना के लिए इस अनुकूलता के महत्व को समझ सकता हूं।
फर्नांडो लील

ऑफ़लाइन टेम्प्लेट कंपाइलर (OTC) अभी तक कार्यात्मक नहीं है, हालांकि यह पहले से ही RC.3 में शामिल है। ओटीसी डेकोरेटर्स का विश्लेषण करेगा और एक निर्माण चरण के दौरान कोड उत्पन्न करेगा जब तैनाती योग्य उत्पन्न होती है। OTC एंगुलर 2 पार्सर और संकलक को हटाने की अनुमति देता है जो रनटाइम पर सज्जाकार और बाइंडिंग की प्रक्रिया करता है, जिससे उल्लेखनीय छोटे कोड आकार और तेजी से अनुप्रयोग और घटक आरंभीकरण होता है। अगले अद्यतन में से एक के साथ ओटीसी संभव हो जाएगा।
गुंटर ज़ोचबॉयर

1
@ गुंटरेज़ोच्बाउर, अब मैं ओटीसी के साथ कार्यक्षमता को बनाए रखने में महत्व को समझता हूं। यह घटकों को इनिशियलाइज़ करने के लिए ओवरहेड को कम करने वाले कोणीय सज्जाकारों का एक पूर्व-संकलन होगा। मैं इस प्रक्रिया के कामकाज के बारे में जानना चाहता हूं और क्योंकि इस उत्तर का समाधान ओटीसी के साथ संगत नहीं होगा? सज्जाकारों का पूर्व संकलन कैसे है? इस ज्ञान के बाद, हम कुछ सोच सकते हैं कि इस कार्यात्मक विकल्प को ओटीसी के लिए रखा जाए। सफाई देने के लिए धन्यवाद!
फर्नांडो लील

24

कोणीय 2 संस्करण 2.3 को अभी जारी किया गया था, और इसमें मूल घटक वंशानुक्रम शामिल है। ऐसा लगता है कि आप टेम्पलेट और शैलियों को छोड़कर, जो कुछ भी आप चाहते हैं उसे विरासत में प्राप्त कर सकते हैं और ओवरराइड कर सकते हैं। कुछ संदर्भ:


यहां एक "गोच" तब होता है जब आप बच्चे के घटक में एक नया "चयनकर्ता" निर्दिष्ट करना भूल जाते हैं। More than one component matched on this elementयदि आप नहीं करते हैं , तो आप की तर्ज पर एक रनटाइम त्रुटि मिलेगी।
ऐल्फिन

@TheAelfinn हाँ: प्रत्येक घटक को @Component()टैग में पूर्ण कल्पना करनी होगी । लेकिन, आप चाहें तो उसी फ़ाइल का संदर्भ देकर .html या .css साझा कर सकते हैं। सब सब में, यह एक बड़ा प्लस है।
डैनियल ग्रिसकॉम

आपके दूसरे लिंक scotch.io/tutorials/component-inheritance-in-angular-2 में , लेखक का दावा है कि घटक अपने माता-पिता की निर्भरता इंजेक्शन सेवाओं को विरासत में देते हैं, मेरा कोड अन्यथा सुझाव देता है। क्या आप पुष्टि कर सकते हैं कि यह समर्थित है?
ऐल्फिन

18

अब जब टाइपस्क्रिप्ट 2.2 क्लास एक्सप्रेशंस के माध्यम से मिक्सिंस का समर्थन करता है तो हमारे पास मिक्सिंस को अवयवों पर व्यक्त करने का एक बेहतर तरीका है। आप पर ध्यान दें कि आप कोणीय 2.3 ( चर्चा ) या एक कस्टम डेकोरेटर के बाद से घटक उत्तराधिकार का उपयोग कर सकते हैं जैसा कि यहां अन्य उत्तरों में चर्चा की गई है। हालाँकि, मुझे लगता है कि मिक्सिंस में कुछ गुण हैं जो उन्हें घटकों के व्यवहार को पुन: उपयोग करने के लिए बेहतर बनाते हैं:

  • मिक्सिंस अधिक लचीले ढंग से रचना करते हैं, अर्थात आप मौजूदा घटकों पर मिक्सिन्स को मिला सकते हैं और नए घटकों को बनाने के लिए मिक्सिंस को मिला सकते हैं
  • मिक्सिन रचना एक वर्ग वंशानुक्रम पदानुक्रम के लिए इसके स्पष्ट रैखिककरण के लिए धन्यवाद समझना आसान रहता है
  • आप डेकोरेटर इनहेरिटेंस ( चर्चा ) में डेकोरेटर और एनोटेशन वाले मुद्दों से आसानी से बच सकते हैं

मैं दृढ़ता से सुझाव देता हूं कि मिक्सिन्स कैसे काम करते हैं, यह समझने के लिए आप ऊपर टाइपस्क्रिप्ट 2.2 की घोषणा पढ़ें। कोणीय GitHub मुद्दों में लिंक की गई चर्चा अतिरिक्त विस्तार प्रदान करती है।

आपको इन प्रकारों की आवश्यकता होगी:

export type Constructor<T> = new (...args: any[]) => T;

export class MixinRoot {
}

और फिर आप इस Destroyableमिक्सिन की तरह एक मिक्सचर की घोषणा कर सकते हैं जो घटकों को सब्सक्रिप्शन का ट्रैक रखने में मदद करता है जिन्हें निपटाने की आवश्यकता होती हैngOnDestroy :

export function Destroyable<T extends Constructor<{}>>(Base: T) {
  return class Mixin extends Base implements OnDestroy {
    private readonly subscriptions: Subscription[] = [];

    protected registerSubscription(sub: Subscription) {
      this.subscriptions.push(sub);
    }

    public ngOnDestroy() {
      this.subscriptions.forEach(x => x.unsubscribe());
      this.subscriptions.length = 0; // release memory
    }
  };
}

मिश्रण करने के लिए DestroyableaComponent , तो आप इस तरह अपने घटक की घोषणा:

export class DashboardComponent extends Destroyable(MixinRoot) 
    implements OnInit, OnDestroy { ... }

ध्यान दें कि MixinRootकेवल तभी आवश्यक है जब आप चाहते हैंextend मिक्सिन रचना । आप आसानी से कई मिश्रणों को बढ़ा सकते हैं जैसे A extends B(C(D))। यह उन मिश्रणों का स्पष्ट रैखिककरण है जिनके बारे में मैं ऊपर बात कर रहा था, जैसे कि आप प्रभावी रूप से एक वंशानुक्रम पदानुक्रम की रचना कर रहे हैं A -> B -> C -> D

अन्य मामलों में, उदाहरण के लिए, जब आप किसी मौजूदा वर्ग पर मिक्सिंस की रचना करना चाहते हैं, तो आप मिक्सिन को इस तरह से लागू कर सकते हैं:

const MyClassWithMixin = MyMixin(MyClass);

हालाँकि, मैंने पाया कि पहला तरीका सबसे अच्छा काम करता है Componentsऔर Directives, क्योंकि इनको भी @Componentया @Directiveकिसी भी तरह से सजाया जाना चाहिए ।


यह कमाल का है! सलाह के लिये धन्यवाद। क्या MixinRoot को यहाँ एक खाली वर्ग प्लेसहोल्डर के रूप में इस्तेमाल किया जा रहा है? बस यह सुनिश्चित करना चाहता हूं कि मेरी समझ सही हो।
एलेक्स लॉकवुड

@AlexLockwood हाँ, खाली वर्ग प्लेसहोल्डर वही है जो मैं इसके लिए उपयोग कर रहा हूं। मैं ख़ुशी से इसका उपयोग करने से बचता हूँ, लेकिन अभी तक मुझे इसे करने का बेहतर तरीका नहीं मिला है।
जोहान्स रुडोल्फ

2
मैंने उपयोग करना समाप्त कर दिया function Destroyable<T extends Constructor<{}>>(Base = class { } as T)। इस तरह मैं मिश्रण का उपयोग कर बना सकते हैं extends Destroyable()
एलेक्स लॉकवुड

1
यह बहुत अच्छा लग रहा है, हालांकि ऐसा लगता है कि एओटी बिल्ड (Cli1.3) डैशबॉयरकॉर्पेंट से ngOnDestroy को हटा देता है क्योंकि इसे कभी भी कॉल नहीं किया जाता है। (वही ngOnInit के लिए जाता है)
dzolnjan

इस समाधान के लिए धन्यवाद। हालांकि आयनिक या कोणीय-क्लि के साथ एक निर्माण के बाद, मिक्सिन किसी तरह काम नहीं करता है, जैसे कि इसे बढ़ाया नहीं गया है।
हान चे

16

अपडेट करें

घटक विरासत 2.3.0-rc.0 के बाद से समर्थित है

मूल

अब तक, मेरे लिए सबसे सुविधाजनक टेम्पलेट और शैलियों को अलग-अलग *htmlऔर *.cssफाइलों में रखना और उन के माध्यम से निर्दिष्ट करना है , templateUrlऔर styleUrlsइसलिए यह आसान पुन: प्रयोज्य है।

@Component {
    selector: 'my-panel',
    templateUrl: 'app/components/panel.html', 
    styleUrls: ['app/components/panel.css']
}
export class MyPanelComponent extends BasePanelComponent

2
यह ठीक वैसा ही है जैसा मुझे चाहिए। BasePanelComponent के लिए @Component डेकोरेटर कैसा दिखेगा? क्या यह अलग HTML / css फाइलों को संदर्भित कर सकता है? यह MyPanelComponent द्वारा संदर्भित उसी HTML / css फ़ाइलों का संदर्भ दे सकता है?
ebhh2001 4

1
यह विरासत @Input()और @Output()सज्जाकार नहीं करता है , यह करता है?
लियोन एडलर

10

जहां तक ​​मुझे पता है कि घटक विरासत को अभी तक कोणीय 2 में लागू नहीं किया गया है और मुझे यकीन नहीं है कि अगर उनके पास योजना है, लेकिन चूंकि अंगुलर 2 टाइपस्क्रिप्ट का उपयोग कर रहा है (यदि आपने उस मार्ग पर जाने का फैसला किया है) तो आप वर्ग विरासत का उपयोग कर सकते हैं करके class MyClass extends OtherClass { ... }। घटक उत्तराधिकार के लिए मैं https://github.com/angular/angular/issues पर जाकर फ़ीचर अनुरोध सबमिट करके कोणीय 2 परियोजना में शामिल होने का सुझाव दूंगा !


समझ गया, मैं अगले दिनों में कोशिश करूंगा कि मुझे angular2 प्रोजेक्ट को पुन: प्रदर्शित किया जाए और अनुरोध सुविधा को सत्यापित किया जाए कि यह अब Git में प्रोजेक्ट के मुद्दों में नहीं है और यदि नहीं, तो मैं संसाधन के लिए अनुरोध करूंगा, क्योंकि यह मुझे बहुत दिलचस्प लगता है सुविधा। कोई भी अतिरिक्त तर्क सबसे दिलचस्प अनुरोध करने के लिए विचार करता है?
फर्नांडो लील

1
विरासत संसाधन के टाइपस्क्रिप्ट के बारे में मैं पहले से ही अपने प्रारंभिक समाधान ( export class MyPanelComponent extends BasePanelComponent) में उपयोग कर रहा हूं , समस्या केवल एनोटेशन / डेकोरेटर्स को विरासत में नहीं मिली है।
फर्नांडो लील

1
हाँ, मैं वास्तव में नहीं जानता कि आप और क्या जोड़ सकते हैं। मुझे या तो एक नया डेकोरेटर (कुछ ऐसा @SubComponent()) होने का विचार पसंद है, जो एक वर्ग को एक उप-समूह के रूप में चिह्नित करता है या @Componentडेकोरेटर पर एक अतिरिक्त क्षेत्र होने के कारण आपको मूल घटक से संदर्भ देने की अनुमति देता है।
वाटसन

1
फ़ीचर अनुरोध कोणीय 2 को GitHub पर प्रोजेक्ट में जोड़ा गया: विस्तार करें / Inherit कोणीय 2 घटक एनोटेशन # 7968
फर्नांडो लील

9

आइए हम कोणीय के घटक विरासत प्रणाली पर कुछ प्रमुख सीमाओं और विशेषताओं को समझें।

घटक केवल वर्ग तर्क विरासत में मिलता है:

  • @Component डेकोरेटर में सभी मेटा-डेटा को विरासत में नहीं मिला है।
  • घटक @Input गुण और @Output गुण विरासत में मिले हैं।
  • घटक जीवनचक्र विरासत में नहीं मिला है।

इन विशेषताओं को ध्यान में रखना बहुत आवश्यक है तो आइए हम प्रत्येक की स्वतंत्र रूप से जांच करें।

घटक केवल वर्ग तर्क को विरासत में मिला है

जब आप किसी घटक को विरासत में लेते हैं, तो अंदर का सभी तर्क समान रूप से विरासत में मिलता है। यह ध्यान देने योग्य है कि केवल सार्वजनिक सदस्यों को विरासत में मिला है क्योंकि निजी सदस्य केवल उस वर्ग में सुलभ हैं जो उन्हें लागू करता है।

@Component डेकोरेटर में सभी मेटा-डेटा को विरासत में नहीं मिला है

तथ्य यह है कि कोई मेटा-डेटा विरासत में नहीं मिला है, पहली बार में काउंटर-सहज ज्ञान युक्त लग सकता है, लेकिन अगर आप इस बारे में सोचते हैं तो यह वास्तव में सही समझ में आता है। यदि आप किसी कंपोनेंट (घटक) से विरासत में मिलते हैं, तो आप नहीं चाहेंगे कि कंपोनेंट का चयनकर्ता, जिसे आप कंपोनेंटबी के चयनकर्ता को बदलने के लिए विरासत में दे रहे हैं, जो कि विरासत में मिला वर्ग है। टेम्प्लेट / टेम्पलेट यूआरएल के साथ-साथ शैली / स्टाइल के लिए भी यही कहा जा सकता है।

घटक @Input और @Output गुण विरासत में मिले हैं

यह एक और विशेषता है जो मुझे वास्तव में कोणीय में घटक विरासत के बारे में पसंद है। एक साधारण वाक्य में, जब भी आपके पास @Input और @Output संपत्ति होती है, तो ये गुण विरासत में मिलते हैं।

घटक जीवनचक्र विरासत में नहीं मिला है

यह हिस्सा वह है जो विशेष रूप से ऐसे लोगों के लिए स्पष्ट नहीं है, जिन्होंने बड़े पैमाने पर ओओपी सिद्धांतों के साथ काम नहीं किया है। उदाहरण के लिए, मान लीजिए कि आपके पास कंपोनेंट है जो Angular के कई जीवनचक्र के हुक जैसे OnInit को लागू करता है। यदि आप कंपोनेंटब बनाते हैं और इनहेरिट कंपोनेंट बनाते हैं, तो कंपोनेंट से ऑनइंड जीवनचक्र तब तक फायर नहीं करेगा जब तक कि आप स्पष्ट रूप से कॉल नहीं करते हैं, भले ही आपके पास कंपोनेंटबी के लिए यह ऑनइनाइक जीवनचक्र हो।

सुपर / बेस घटक विधियों को कॉल करना

ComponentA आग से ngOnInit () विधि प्राप्त करने के लिए, हमें सुपर कीवर्ड का उपयोग करने की आवश्यकता है और फिर हमें उस विधि को कॉल करना होगा जो इस मामले में ngOnInit है। सुपर कीवर्ड उस घटक के उदाहरण को संदर्भित करता है जो विरासत में मिला है, जिसमें से इस मामले में ComponentA होगा।


5

यदि आप CDK पुस्तकालयों और सामग्री पुस्तकालयों के माध्यम से पढ़ते हैं, तो वे इनहेरिटेंस का उपयोग कर रहे हैं, लेकिन स्वयं घटकों के लिए इतना नहीं है, सामग्री का प्रक्षेपण राजा IMO है। इस लिंक को देखें https://blog.angular-university.io/angular-ng-content/ जहाँ यह कहता है कि "इस डिज़ाइन की मुख्य समस्या"

मुझे पता है कि यह आपके सवाल का जवाब नहीं देता है लेकिन मुझे लगता है कि इनहेरिट करने / फैलाने वाले घटकों से बचा जाना चाहिए । यहाँ मेरा तर्क है:

यदि दो या दो से अधिक घटकों द्वारा विस्तारित सार वर्ग में साझा तर्क होते हैं: एक सेवा का उपयोग करें या यहां तक ​​कि एक नया टाइपस्क्रिप्ट वर्ग बनाएं जो दो घटकों के बीच साझा किया जा सकता है।

यदि अमूर्त वर्ग ... में साझा चर या onClicketc फ़ंक्शन शामिल हैं, तो दो अतिरिक्त घटक विचारों के HTML के बीच दोहराव होगा। यह बुरा अभ्यास है और साझा किए गए HTML को घटक (एस) में तोड़ने की आवश्यकता है। इन घटक (भागों) को दो घटकों के बीच साझा किया जा सकता है।

क्या मुझे घटकों के लिए एक सार वर्ग होने के अन्य कारण याद आ रहे हैं?

एक उदाहरण जो मैंने हाल ही में देखा, वह था AutoUnsubscribe करने वाले घटक:

import { Subscription } from 'rxjs';
import { OnDestroy } from '@angular/core';
export abstract class AutoUnsubscribeComponent implements OnDestroy {
  protected infiniteSubscriptions: Array<Subscription>;

  constructor() {
    this.infiniteSubscriptions = [];
  }

  ngOnDestroy() {
    this.infiniteSubscriptions.forEach((subscription) => {
      subscription.unsubscribe();
    });
  }
}

यह आधार था क्योंकि एक बड़े कोडबेस में, infiniteSubscriptions.push()केवल 10 बार उपयोग किया गया था। इसके अलावा आयात और विस्तार AutoUnsubscribeवास्तव mySubscription.unsubscribe()में केवल ngOnDestroy()घटक की विधि में जोड़ने की तुलना में अधिक कोड लेता है, जिसे वैसे भी अतिरिक्त तर्क की आवश्यकता होती है।


ठीक है, मैं आपके सहयोग को समझता हूं और मैं मानता हूं कि एकत्रीकरण उन सभी समस्याओं को हल करता है जो विरासत की जरूरत लगती हैं। और एप्लिकेशन के छोटे भागों के रूप में घटकों के बारे में सोचना हमेशा दिलचस्प होता है, जिन्हें कई तरीकों से डॉक किया जा सकता है। लेकिन सवाल के मामले में समस्या यह है कि मुझे उस घटक में संशोधनों के लिए नियंत्रण / पहुंच नहीं है जिसे मैं विरासत में देना चाहता हूं (यह एक तीसरा घटक है), फिर एकत्रीकरण अक्षम हो जाएगा, और विरासत आदर्श समाधान होगा।
फर्नांडो लील

आप सिर्फ एक नया घटक क्यों नहीं बना सकते जो उस तीसरे पक्ष के घटक को घेरता है? आपका तीसरा पक्ष घटक क्या है? जैसे <मेरा-कैलेंडर [सामान] = सामान> <तीसरा-पार्टी-कैलेंडर [सामान] = सामान> </ ..> </ ..>
रोबर्ट राजा

@robertking अपने आप को दोहराना बहुत कमजोर पैटर्न है ... यही कारण है कि आप अपनी नौकरी से नफरत करना शुरू कर देंगे .. बजाय आनंद लेने के।
डेरियस फिलीपिआक

मेरे लिए जैसा कि आप घटकों के एक सेट के लिए एक ही इनपुट / आउटपुट पैरामेट्स चाहते हैं, तो घटकों का विस्तार करना एक अच्छा विचार है, इसलिए वे एक के रूप में व्यवहार कर सकते हैं। उदाहरण के लिए मेरे पास कई पंजीकरण चरण हैं (क्रेडेंशियल्सस्टेप, एड्रेसस्टेप, सेलेबिटीसस्टेप)। उन सभी के पास एक ही इनपुट विकल्प (stepName, actionButtons ...) और आउटपुट (पूर्ण, रद्द) होना चाहिए।
सर्गेई_T

@Sergey_T क्या आप एनजी चयन और सामग्री प्रक्षेपण के साथ एक घटक पर विचार कर सकते हैं? इसके अलावा कुछ इनपुट को दोहराने से ऐसा नहीं लगता है कि आप वास्तव में ज्यादा कार्यक्षमता वाले टीबीएच पर बचत कर रहे हैं।
रॉबर्ट राजा

2

अगर किसी को एक अद्यतन समाधान की तलाश है, तो फर्नांडो का जवाब बहुत ज्यादा सही है। सिवाय इसके कि ComponentMetadataपदावनत कर दिया गया है। Componentइसके बजाए मेरे लिए काम करना ।

पूर्ण कस्टम डेकोरेटर CustomDecorator.tsफ़ाइल इस तरह दिखाई देती है:

import 'zone.js';
import 'reflect-metadata';
import { Component } from '@angular/core';
import { isPresent } from "@angular/platform-browser/src/facade/lang";

export function CustomComponent(annotation: any) {
  return function (target: Function) {
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);

    var parentAnnotation = parentAnnotations[0];
    Object.keys(parentAnnotation).forEach(key => {
      if (isPresent(parentAnnotation[key])) {
        // verify is annotation typeof function
        if(typeof annotation[key] === 'function'){
          annotation[key] = annotation[key].call(this, parentAnnotation[key]);
        }else if(
          // force override in annotation base
          !isPresent(annotation[key])
        ){
          annotation[key] = parentAnnotation[key];
        }
      }
    });

    var metadata = new Component(annotation);

    Reflect.defineMetadata('annotations', [ metadata ], target);
  }
}

फिर अपने नए घटक को में आयात sub-component.component.tsफ़ाइल और प्रयोग @CustomComponentके बजाय @Componentइस तरह:

import { CustomComponent } from './CustomDecorator';
import { AbstractComponent } from 'path/to/file';

...

@CustomComponent({
  selector: 'subcomponent'
})
export class SubComponent extends AbstractComponent {

  constructor() {
    super();
  }

  // Add new logic here!
}

कस्टम सज्जाकार सलाह बिल्कुल नहीं कर रहे हैं? कई अन्य पोस्ट / थ्रेड्स से इस समाधान को पूरी तरह से गलत के रूप में चिह्नित किया गया है क्योंकि एओटी उनका समर्थन नहीं करेगा?
टेरनोवी

2

आप इनहेरिट कर सकते हैं @Input, @Output, @ViewChild, आदि। नमूना देखें:

@Component({
    template: ''
})
export class BaseComponent {
    @Input() someInput: any = 'something';

    @Output() someOutput: EventEmitter<void> = new EventEmitter<void>();

}

@Component({
    selector: 'app-derived',
    template: '<div (click)="someOutput.emit()">{{someInput}}</div>',
    providers: [
        { provide: BaseComponent, useExisting: DerivedComponent }
    ]
})
export class DerivedComponent {

}

1

घटकों को एक टाइपस्क्रिप्ट वर्ग विरासत के रूप में ही बढ़ाया जा सकता है, बस आपको नए नाम के साथ चयनकर्ता को ओवरराइड करना होगा। मूल इनपुट से सभी इनपुट () और आउटपुट () गुण सामान्य के रूप में काम करते हैं

अपडेट करें

@Component, एक डेकोरेटर है

डेकोरेटर्स को वस्तुओं पर नहीं कक्षा की घोषणा के दौरान लागू किया जाता है।

मूल रूप से, सज्जाकार वर्ग वस्तु में कुछ मेटाडेटा जोड़ते हैं और जिसे वंशानुक्रम के माध्यम से एक्सेस नहीं किया जा सकता है।

यदि आप डेकोरेटर इनहेरिटेंस प्राप्त करना चाहते हैं, तो मैं एक कस्टम डेकोरेटर लिखना चाहूंगा। उदाहरण के नीचे कुछ।

export function CustomComponent(annotation: any) {
    return function (target: Function) {
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;

    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);
    var parentParamTypes = Reflect.getMetadata('design:paramtypes', parentTarget);
    var parentPropMetadata = Reflect.getMetadata('propMetadata', parentTarget);
    var parentParameters = Reflect.getMetadata('parameters', parentTarget);

    var parentAnnotation = parentAnnotations[0];

    Object.keys(parentAnnotation).forEach(key => {
    if (isPresent(parentAnnotation[key])) {
        if (!isPresent(annotation[key])) {
        annotation[key] = parentAnnotation[key];
        }
    }
    });
    // Same for the other metadata
    var metadata = new ComponentMetadata(annotation);

    Reflect.defineMetadata('annotations', [ metadata ], target);
    };
};

देखें: https://medium.com/@ttemplier/angular2-decorators-and-class-inheritance-905921dbd1b7


क्या आप इस सवाल का उदाहरण दे सकते हैं कि यह कैसे काम करेगा? आप उदाहरण विकसित करने और लिंक साझा करने के लिए स्टैकब्लिट्ज़ का उपयोग कर सकते हैं ।
फर्नांडो लील

@Component एक डेकोरेटर है, डेकोरेटर्स वस्तुओं पर नहीं कक्षा की घोषणा के दौरान लगाए जाते हैं।
महाशय वलीता

तुम सही हो। सज्जाकार कोई फर्क नहीं करते हैं। यह तभी आवश्यक है जब आधार घटक को घटक के रूप में कहीं और प्रयोग किया जाए
MAHESH VALIYA VEETIL

0
just use inheritance,Extend parent class in child class and declare constructor with parent class parameter and this parameter use in super().

1.parent class
@Component({
    selector: 'teams-players-box',
    templateUrl: '/maxweb/app/app/teams-players-box.component.html'
})
export class TeamsPlayersBoxComponent {
    public _userProfile:UserProfile;
    public _user_img:any;
    public _box_class:string="about-team teams-blockbox";
    public fullname:string;
    public _index:any;
    public _isView:string;
    indexnumber:number;
    constructor(
        public _userProfilesSvc: UserProfiles,
        public _router:Router,
    ){}
2.child class
@Component({

    selector: '[teams-players-eligibility]',
    templateUrl: '/maxweb/app/app/teams-players-eligibility.component.html'
})
export class TeamsPlayersEligibilityComponent extends TeamsPlayersBoxComponent{

    constructor (public _userProfilesSvc: UserProfiles,
            public _router:Router) {
            super(_userProfilesSvc,_router);
        }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.