एक और विकल्प।
ओपी ने कॉलबैक का उपयोग करने का तरीका पूछा। इस मामले में वह विशेष रूप से एक फ़ंक्शन का उल्लेख कर रहे थे जो एक घटना की प्रक्रिया करता है (उनके उदाहरण में: एक क्लिक घटना), जिसे @serginho से स्वीकृत उत्तर के रूप में माना जाएगा: के साथ @Output
और EventEmitter
।
हालाँकि, कॉलबैक और ईवेंट के बीच अंतर होता है: कॉलबैक से आपका चाइल्ड कंपोनेंट अभिभावक से कुछ फीडबैक या जानकारी प्राप्त कर सकता है, लेकिन एक ईवेंट केवल यह सूचित कर सकता है कि कोई प्रतिक्रिया की अपेक्षा के बिना कुछ हुआ।
ऐसे मामले हैं जहां एक प्रतिक्रिया आवश्यक है, पूर्व। एक रंग, या उन तत्वों की एक सूची प्राप्त करें जिन्हें घटक को संभालना है। आप बंधे हुए कार्यों का उपयोग कर सकते हैं जैसा कि कुछ उत्तरों ने सुझाया है, या आप इंटरफेस का उपयोग कर सकते हैं (यह हमेशा मेरी प्राथमिकता है)।
उदाहरण
मान लीजिए कि आपके पास एक सामान्य घटक है जो तत्वों की एक सूची {आईडी, नाम} पर काम करता है जिसे आप अपने सभी डेटाबेस तालिकाओं के साथ उपयोग करना चाहते हैं जिनके पास ये क्षेत्र हैं। यह घटक चाहिए:
- तत्वों (पेज) की एक श्रृंखला को पुनः प्राप्त करें और उन्हें एक सूची में दिखाएं
- एक तत्व को हटाने की अनुमति दें
- सूचित करें कि एक तत्व पर क्लिक किया गया था, इसलिए अभिभावक कुछ कार्रवाई कर सकते हैं।
- तत्वों के अगले पृष्ठ को पुनः प्राप्त करने की अनुमति दें।
बाल घटक
सामान्य बंधन का उपयोग करके हमें 1 @Input()
और 3 @Output()
मापदंडों की आवश्यकता होगी (लेकिन माता-पिता से किसी भी प्रतिक्रिया के बिना)। पूर्व। <list-ctrl [items]="list" (itemClicked)="click($event)" (itemRemoved)="removeItem($event)" (loadNextPage)="load($event)" ...>
, लेकिन एक इंटरफ़ेस बनाने के लिए हमें केवल एक की आवश्यकता होगी @Input()
:
import {Component, Input, OnInit} from '@angular/core';
export interface IdName{
id: number;
name: string;
}
export interface IListComponentCallback<T extends IdName> {
getList(page: number, limit: number): Promise< T[] >;
removeItem(item: T): Promise<boolean>;
click(item: T): void;
}
@Component({
selector: 'list-ctrl',
template: `
<button class="item" (click)="loadMore()">Load page {{page+1}}</button>
<div class="item" *ngFor="let item of list">
<button (click)="onDel(item)">DEL</button>
<div (click)="onClick(item)">
Id: {{item.id}}, Name: "{{item.name}}"
</div>
</div>
`,
styles: [`
.item{ margin: -1px .25rem 0; border: 1px solid #888; padding: .5rem; width: 100%; cursor:pointer; }
.item > button{ float: right; }
button.item{margin:.25rem;}
`]
})
export class ListComponent implements OnInit {
@Input() callback: IListComponentCallback<IdName>; // <-- CALLBACK
list: IdName[];
page = -1;
limit = 10;
async ngOnInit() {
this.loadMore();
}
onClick(item: IdName) {
this.callback.click(item);
}
async onDel(item: IdName){
if(await this.callback.removeItem(item)) {
const i = this.list.findIndex(i=>i.id == item.id);
this.list.splice(i, 1);
}
}
async loadMore(){
this.page++;
this.list = await this.callback.getList(this.page, this.limit);
}
}
जनक घटक
अब हम सूची घटक का उपयोग अभिभावक में कर सकते हैं।
import { Component } from "@angular/core";
import { SuggestionService } from "./suggestion.service";
import { IdName, IListComponentCallback } from "./list.component";
type Suggestion = IdName;
@Component({
selector: "my-app",
template: `
<list-ctrl class="left" [callback]="this"></list-ctrl>
<div class="right" *ngIf="msg">{{ msg }}<br/><pre>{{item|json}}</pre></div>
`,
styles:[`
.left{ width: 50%; }
.left,.right{ color: blue; display: inline-block; vertical-align: top}
.right{max-width:50%;overflow-x:scroll;padding-left:1rem}
`]
})
export class ParentComponent implements IListComponentCallback<Suggestion> {
msg: string;
item: Suggestion;
constructor(private suggApi: SuggestionService) {}
getList(page: number, limit: number): Promise<Suggestion[]> {
return this.suggApi.getSuggestions(page, limit);
}
removeItem(item: Suggestion): Promise<boolean> {
return this.suggApi.removeSuggestion(item.id)
.then(() => {
this.showMessage('removed', item);
return true;
})
.catch(() => false);
}
click(item: Suggestion): void {
this.showMessage('clicked', item);
}
private showMessage(msg: string, item: Suggestion) {
this.item = item;
this.msg = 'last ' + msg;
}
}
ध्यान दें कि कॉलबैक ऑब्जेक्ट के रूप में <list-ctrl>
प्राप्त this
(मूल घटक)। एक अतिरिक्त लाभ यह है कि यह मूल उदाहरण भेजने के लिए आवश्यक नहीं है, यह एक सेवा या कोई भी वस्तु हो सकती है जो इंटरफ़ेस का उपयोग करता है यदि आपका उपयोग मामला अनुमति देता है।
पूरा उदाहरण इस स्टैकब्लिट्ज पर है ।
@Input
जिस तरह से सुझाव दिया गया कि मेरे कोड को स्पैगेटी बना दिया जाए और उसे बनाए रखना आसान नहीं है ..@Output
मैं जो चाहता हूं, वह करने का एक और अधिक प्राकृतिक तरीका है। परिणामस्वरूप मैंने स्वीकार किए गए उत्तर को बदल दिया