दिलचस्प पोस्ट
तस्वीरों के रूप में चित्रों को या वेब ऐप के लिए डेटाबेस में स्टोर करें? स्ट्रिंग को सी में दो में परिवर्तित करना # आर में जीजीप्लोट 2 में अंकों को नियंत्रित करना? जावा – बंद स्कैनर और संसाधन रिसाव पायथन में रिक्त ऑब्जेक्ट? ऑर्डर किए गए आदेश को लागू करने के लिए इस फ़ंक्शन को कैसे पुनः लिखा जा सकता है? सिगविन के अंतर्गत जीसीसी के उपयोग से निष्पादन योग्य फ़ाइल उत्पन्न होती है हाइबरनेट: "फील्ड 'आईडी' का कोई डिफ़ॉल्ट मान नहीं है" नेस्टेड स्क्रॉल वीव के अंदर रिसाइक्लर का उपयोग कैसे करें? InputStream.available () जावा में क्या करता है? क्या मैं विम में Alt कुंजी को मैप सकता हूँ? पैरामीटर के साथ अंतर। जोड़ें और पैरामीटर। AddWithValue jquery (या शुद्ध जे एस) अनुकरण परीक्षण के लिए दबाया कुंजी दर्ज करें एक शाखा की तरह एक शाखा बनाने के लिए git कमांड एंड्रॉइड: उपयोगकर्ता नाम और पासवर्ड भंडारण?

कोणीय 2 – डायनेमिकली निर्मित तत्व में घटक

मैं Google नक्शे जावास्क्रिप्ट एपीआई का उपयोग करता हूं और मुझे InfoWindow में एक कोणीय घटक प्रदर्शित करना है I

मेरी परियोजना में मैं Jsonp सेवा के साथ Google मानचित्र एपीआई लोड करता हूं मेरे पास google.maps.Map ऑब्जेक्ट उपलब्ध है। बाद में एक घटक में मुझे कुछ मार्कर बनाते हैं और उन्हें एक क्लिक श्रोता देते हैं:

टाइपस्क्रिप्ट :

 let marker = new google.maps.Marker(opts); marker.setValues({placeId: item[0]}); marker.addListener('click', (ev: google.maps.MouseEvent) => this.onMarkerClick(marker, ev)); 

और फिर click हैंडलर में मैं एक सूचना विंडो खोलना चाहता हूं जिसमें एक कोनाल घटक होता है:

टाइपस्क्रिप्ट :

 private onMarkerClick(marker: google.maps.Marker, ev: google.maps.MouseEvent) { var div = document.createElement(); this.placeInfoWindow.setContent(div); // Magic should happen here somehow // this.placeInfoWindow.setContent('<app-info-view-element></app-info-view-element>'); this.placeInfoWindow.open(this.map, marker); } 

मैं क्या कर रहा था कुछ वेनिला जेएस:

टाइपस्क्रिप्ट :

  private onMarkerClick(marker: google.maps.Marker, ev: google.maps.MouseEvent) { let div = document.createElement('div'); div.className = 'map-info-window-container'; div.style.height = '140px'; div.style.width = '240px'; this.placeInfoWindow.setContent(div); this.placeInfoWindow.open(this.map, marker); this.placesService.getPlace(marker.get('id')).subscribe(res => { this.decorateInfoWindow(div, res.name, marker); }, error => { this.decorateInfoWindow(div, ':( Failed to load details: ', marker); }); } private decorateInfoWindow(containerEl: HTMLElement, title?:string, marker?:google.maps.Marker) { let h3 = document.createElement('h3'); h3.innerText = title; containerEl.appendChild(h3); let buttonBar = document.createElement('div'); let editButton = document.createElement('button') editButton.innerText = "Edit"; editButton.addEventListener('click', ev => { this.editPlace(marker); }); buttonBar.appendChild(editButton); containerEl.appendChild(buttonBar); } 

समस्या, जैसा कि मैंने सीखा है, क्या यह है कि गतिशील घटकों को बनाने का एकमात्र व्यवहार्य तरीका है कांच का दृश्यकंटिएररफ का उपयोग करना:

  • एक कंटेनर में एक गतिशील घटक कैसे रखा जाए

लेकिन कोई डॉक्स या उदाहरण नहीं हैं, जो गतिशील रूप से बनाए गए तत्व से ViewContainerRef बनाने का वर्णन करता है।


क्या यह DOM को किसी तरह से संसाधित करने के लिए ढांचे को लागू करने के लिए सक्षम है? चूंकि यह कई धागे में है: "कोणीय appendChild innerHTML या appendChild प्रोसेस नहीं करता है" क्या यह एक पूरी तरह खत्म हो गया है?

दूसरा: क्या Renderer कार्यान्वयन का उपयोग करना संभव है? (इसके बारे में पता नहीं है), मैंने यह कैनवास रेंडरर प्रयोग और सैद्धांतिक रूप से देखा, मुझे लगता है कि यह गूगल मैप के साथ भी काम करेगा, क्योंकि हम एक्सट्रपलेशन कर सकते हैं कि नक्शा सिर्फ एक विशेष प्रकार का कैनवास है। क्या यह अभी भी पिछले रिलीज में उपलब्ध है या इसे बदल दिया है? DomRenderer डॉक्स में नहीं है, हालांकि कोई इसे स्रोतों में ढूँढ सकता है

Solutions Collecting From Web of "कोणीय 2 – डायनेमिकली निर्मित तत्व में घटक"

यहां मुख्य नियम गतिशील रूप से घटक बनाने के लिए आपको अपने कारखाने को प्राप्त करने की आवश्यकता है।

1) declarations में शामिल करने के अलावा entryComponents घटक के सरणी के लिए गतिशील घटक जोड़ें:

 @NgModule({ ... declarations: [ AppInfoWindowComponent, ... ], entryComponents: [ AppInfoWindowComponent, ... ], }) 

यह कोणीय कंपाइलर के लिए घटक के लिए एनजीएफएसीटी का उत्पादन करने के लिए एक संकेत है भले ही हम अपने कुछ टेम्पलेट के अंदर सीधे घटक का उपयोग न करें।

2) अब हमें घटक / फाइबर रिज़ॉलर को अपने घटक / सेवा के लिए इंजेक्ट करना होगा जहां हम एनजीएफटीएटर प्राप्त करना चाहते हैं। आप घटक फैक्टरियों के संग्रहण की तरह ComponentFactoryResolver बारे में सोच सकते हैं

app.component.ts

 import { ComponentFactoryResolver } from '@angular/core' ... constructor(private resolver: ComponentFactoryResolver) {} 

3) यह समय है कि AppInfoWindowComponent कारखाना प्राप्त करें:

 const compFactory = this.resolver.resolveComponentFactory(AppInfoWindowComponent); this.compRef = compFactory.create(this.injector); 

4) कारखाने के बाद हम इसे आसानी से इस्तेमाल कर सकते हैं कि हम कैसे चाहते हैं यहां कुछ मामलों हैं:

  • ViewContainerRef.createComponent(componentFactory,...) को देखने के बगल में घटक सम्मिलित करता है।

  • ComponentFactory.create(injector, projectableNodes?, rootSelectorOrNode?) बस घटक बनाता है और इस घटक को तत्व में सम्मिलित किया जा सकता है जो rootSelectorOrNode मेल खाता है

ध्यान दें कि हम ComponentFactory.create फ़ंक्शन के तीसरे पैरामीटर में नोड या चयनकर्ता प्रदान कर सकते हैं। कई मामलों में यह सहायक हो सकता है। इस उदाहरण में मैं बस घटक बनाऊंगा और फिर कुछ तत्व में डालें।

onMarkerClick विधि की तरह लग सकता है:

 onMarkerClick(marker, e) { if(this.compRef) this.compRef.destroy(); // creation component, AppInfoWindowComponent should be declared in entryComponents const compFactory = this.resolver.resolveComponentFactory(AppInfoWindowComponent); this.compRef = compFactory.create(this.injector); // example of parent-child communication this.compRef.instance.param = "test"; const subscription = this.compRef.instance.onCounterIncremented.subscribe(x => { this.counter = x; }); let div = document.createElement('div'); div.appendChild(this.compRef.location.nativeElement); this.placeInfoWindow.setContent(div); this.placeInfoWindow.open(this.map, marker); // 5) it's necessary for change detection within AppInfoWindowComponent // tips: consider ngDoCheck for better performance this.appRef.attachView(this.compRef.hostView); this.compRef.onDestroy(() => { this.appRef.detachView(this.compRef.hostView); subscription.unsubscribe(); }); } 

5) दुर्भाग्यवश गतिशील रूप से निर्मित घटक परिवर्तन का पता लगाने के पेड़ का हिस्सा नहीं है इसलिए हमें परिवर्तन का पता लगाने के बारे में भी ध्यान रखना होगा। यह ApplicationRef.attachView(compRef.hostView) का उपयोग कर किया जा सकता है जैसा कि ऊपर दिए गए उदाहरण में लिखा गया है या हम इसे ngDoCheck ( उदाहरण के घटक) के साथ ngDoCheck कर सकते हैं जहां हम गतिशील घटक बना रहे हैं (मेरे मामले में AppComponent )

app.component.ts

 ngDoCheck() { if(this.compRef) { this.compRef.changeDetectorRef.detectChanges() } } 

यह दृष्टिकोण बेहतर है क्योंकि वर्तमान घटक अद्यतन किया जाता है, क्योंकि यह केवल गतिशील घटक को अपडेट करेगा। दूसरी ओर, ApplicationRef.attachView(compRef.hostView) में बदल डिटेक्टर बदल डिटेक्टर ट्री के रूट में जोड़ता है और इसलिए इसे प्रत्येक परिवर्तन का पता लगाने वाला टिक कहा जाता है।

प्लंकर उदाहरण


सुझाव:

क्योंकि addListener angular2 क्षेत्र के बाहर चल रहा है हमें explicity को angular2 क्षेत्र के अंदर हमारे कोड चलाने की आवश्यकता है:

 marker.addListener('click', (e) => { this.zone.run(() => this.onMarkerClick(marker, e)); });