2016-02-08 18 views
15

मैं वर्तमान में एक कोणीय 2 प्रोजेक्ट (स्पष्ट रूप से बहुत सारे बदलावों के साथ) में बैकबोन प्रोजेक्ट को पोर्ट करने पर काम कर रहा हूं, और परियोजना आवश्यकताओं में से एक को कुछ विधियों को सार्वजनिक रूप से सुलभ करने की आवश्यकता है।कोणीय 2 विधियों को सार्वजनिक रूप से कैसे बेनकाब करें?

एक त्वरित उदाहरण:

घटक

@component({...}) 
class MyTest { 
    private text:string = ''; 
    public setText(text:string) { 
     this.text = text; 
    } 
} 

जाहिर है, मैं <button (click)="setText('hello world')>Click me!</button> हो सकता था, और मुझे लगता है कि ऐसा करने के लिए और साथ ही चाहते हैं। हालांकि, मैं इसे सार्वजनिक रूप से एक्सेस करने में सक्षम होना चाहता हूं।

इस

<button onclick="angular.MyTest.setText('Hello from outside angular!')"></click> 

की तरह या इस

// in the js console 
angular.MyTest.setText('Hello from outside angular!'); 

किसी भी तरह से, मैं विधि सार्वजनिक रूप से उजागर किया है तो यह कोणीय 2 ऐप्लिकेशन के बाहर कहा जा सकता है करना चाहते हैं।

यह कुछ है जो हमने रीढ़ की हड्डी में किया है, लेकिन मुझे लगता है कि मेरा Google foo कोणीय का उपयोग करके इसके लिए एक अच्छा समाधान खोजने के लिए पर्याप्त मजबूत नहीं है।

हम केवल कुछ तरीकों का पर्दाफाश करना चाहते हैं और सार्वजनिक एपिस की एक सूची है, इसलिए यदि आपके पास ऐसा करने के लिए भी युक्तियां हैं, तो यह एक अतिरिक्त बोनस होगा। (मेरे पास विचार हैं, लेकिन दूसरों का स्वागत है।)

+0

[कोणीय 2 - ऐप के बाहर से घटक फ़ंक्शन को कॉल करने का संभावित डुप्लिकेट] (http://stackoverflow.com/questions/35296704/angular2-how-to-call-component-function-from-outside-the- ऐप) –

+1

@ डेवकेनेडी आप महसूस करते हैं कि यह प्रश्न उस से पहले पोस्ट किया गया था, है ना? – Jacques

उत्तर

17

बस घटक को वैश्विक मानचित्र में पंजीकृत करें और आप इसे वहां से एक्सेस कर सकते हैं।

उपयोग या तो निर्माता या ngOnInit() या अन्य lifecycle hooks के किसी भी घटक रजिस्टर करने के लिए और ngOnDestroy() यह अपंजीकृत करने।

जब आप कोणीय के बाहर से कोणीय तरीकों को कॉल करते हैं, तो कोणीय मॉडल परिवर्तन को पहचान नहीं पाता है। अंगुलर NgZone के लिए यह है। प्राप्त करने के लिए कोणीय क्षेत्र के लिए एक संदर्भ सिर्फ निर्माता

constructor(zone:NgZone) { 
} 

आप zone अपने आप में एक वैश्विक वस्तु में उपलब्ध कराने या तो कर सकते हैं और साथ ही या सिर्फ क्षेत्र के भीतर घटक के अंदर कोड निष्पादित करने के लिए यह इंजेक्षन।

उदाहरण

calledFromOutside(newValue:String) { 
    this.zone.run(() => { 
    this.value = newValue; 
    }); 
} 

या

zone.run(() => { component.calledFromOutside(newValue); }); 

https://plnkr.co/edit/6gv2MbT4yzUhVUfv5u1b?p=preview

की तरह वैश्विक क्षेत्र संदर्भ ब्राउज़र कंसोल आप <topframe> से plunkerPreviewTarget.... करने के लिए स्विच करने के लिए है में उपयोग के लिए

क्योंकि Plunker में कोड निष्पादित करता है एक iFrame।तब

window.angularComponentRef.zone.run(() => {window.angularComponentRef.component.callFromOutside('1');}) 

या

window.angularComponentRef.zone.run(() => {window.angularComponentRef.componentFn('2');}) 
+0

ठीक है, तो मुझे अपने सभी सार्वजनिक तरीकों के लिए सहायक तरीके बनाने की आवश्यकता होगी। आपकी मदद के लिए बहुत बहुत धन्यवाद, बीटीडब्ल्यू। – Jacques

+0

तो, एक ऐसी सेवा बनाने में जो कार्य पंजीकृत करता है, मेरे पास एक ही समस्या है क्योंकि मैंने 'zone.run (() => {}) का उपयोग शुरू करने से पहले किया था, 'विधि पंजीकृत है, और मैं इसे बिना किसी समस्या के कॉल कर सकता हूं हालांकि, ऐसा लगता है कि परिवर्तन का पता चलाना नहीं चल रहा है। 'window.widget [name] =() => { window.zone.run (() => { गुंजाइश [callbackMethod](); }); }; ' उपरोक्त 'स्कोप' घटक है, और जिस विधि को मैं कॉल कर रहा हूं वह 'callbackMethod' है। कोई सुझाव? – Jacques

+0

मैं प्लंकर की सराहना करता हूं, लेकिन मुद्दा यह है कि मेरे पास एक बाहरी सेवा है जो window.widget ऑब्जेक्ट पर विधि जोड़ रही है। मैं विधियों को कॉल कर सकता हूं, लेकिन परिवर्तन का पता लगाना फायरिंग नहीं है।ऐसा लगता है कि आपके उदाहरण में मैं क्या उपयोग कर रहा था जब मैं बाहरी सेवा का उपयोग नहीं कर रहा था। (मैं सिर्फ उस बाहरी सेवा को स्क्रैप कर सकता हूं।) मदद के लिए धन्यवाद। – Jacques

1

चलाने समस्या यह है कि कोणीय के घटकों मॉड्यूल के रूप में नियमित रूप से जावा स्क्रिप्ट कोड का उपयोग करने के रूप में आसान नहीं है में transpiled कर रहे हैं। मॉड्यूल की सुविधाओं तक पहुंचने की प्रक्रिया मॉड्यूल के प्रारूप पर निर्भर करती है।

एक कोणीय 2 कक्षा में स्थैतिक सदस्यों को शामिल किया जा सकता है जिन्हें बिना किसी नए ऑब्जेक्ट को परिभाषित किए परिभाषित किया जा सकता है। आप की तरह कुछ करने के लिए अपने कोड को बदलने के लिए चाहते हो सकता है:

@component({...}) 
class MyTest { 
    private static text: string = ''; 
    public static setText(text:string) { 
     this.text = text; 
    } 
} 
+0

से संबंधित हो सकता है मैं अभी भी घटक सार्वजनिक रूप से बेनकाब करने के लिए एक तरह से की जरूरत नहीं होगी? – Jacques

+0

कोणीय के बाहर एक घटक तक पहुंचने के लिए, आपको पारदर्शी जावास्क्रिप्ट को देखना चाहिए। आम तौर पर, वेब पेज लोडर तक पहुंचकर घटकों को लोड करते हैं ([SystemJS] पर 'System.import' देखें) (https://github.com/systemjs/systemjs))। – MatthewScarpino

+0

systemjs के माध्यम से लोड किए गए घटक डिफ़ॉल्ट रूप से उपलब्ध नहीं हैं, पारदर्शी जेएस को देखने में मदद नहीं करता है क्योंकि जेएस system.register का उपयोग कर लोड हो रहा है। कोणीय (या कोणीय, आदि) वैश्विक क्षेत्र में भी उपलब्ध है, (नहीं है http://stackoverflow.com/questions/34779126/detect-whether-angular2-is-loaded-on-a-page-when-using-systemjs) और हम उत्पादन में systemjs का उपयोग नहीं करेंगे। – Jacques

3

यह कैसे मैं it.my घटक below.dont आयात करने के लिए NgZone.it सबसे महत्वपूर्ण हिस्सा here.its NgZone कि कोणीय जाने है भूल जाते दिया जाता है किया है बाहरी बाहरी संदर्भ को समझने के लिए। zone.run के माध्यम से शानदार कार्यों से आप एंगुलर जोन के बाहर निष्पादित किए गए कार्य से कोणीय क्षेत्र को पुन: प्रस्तुत करने की अनुमति देता है। हमें इसकी आवश्यकता है क्योंकि हम बाहरी कॉल से निपट रहे हैं जो कोणीय क्षेत्र में नहीं है।

import { Component, Input , NgZone } from '@angular/core'; 
import { Router } from '@angular/router'; 

    @Component({ 
     selector: 'example', 
     templateUrl: './example.html', 
    }) 
    export class ExampleComponent { 
      public constructor(private zone: NgZone, private router: Router) { 

//exposing component to the outside here 
//componentFn called from outside and it in return calls callExampleFunction() 
     window['angularComponentReference'] = { 
      zone: this.zone, 
      componentFn: (value) => this.callExampleFunction(value), 
      component: this, 
     }; 
    } 

    public callExampleFunction(value: any): any { 
     console.log('this works perfect'); 
     } 
    } 

अब मेरे मामले मैं अपने index.html.my index.html की स्क्रिप्ट टैग के माध्यम से यहां तक ​​पहुंचने के लिए नीचे दी गई है चाहता था outside.in से इस फोन की सुविधा देता है।

<script> 

//my listener to outside clicks 
ipc.on('send-click-to-AT', (evt, entitlement) => 
electronClick(entitlement));; 

//function invoked upon the outside click event 

function electronClick(entitlement){ 
//this is the important part.call the exposed function inside angular 
//component 

    window.angularComponentReference.zone.run(() = 
    {window.angularComponentReference.componentFn(entitlement);}); 
} 
</script> 

तुम सिर्फ नीचे टाइप डेवलपर कंसोल में है और यह उजागर विधि लागू करेगा और 'यह सही काम करता है' कंसोल पर प्रिंट किया जाएगा Enter दबाएँ।

window.angularComponentReference.zone.run(() = 
{window.angularComponentReference.componentFn(1);}); 

एंटाइटेलमेंट केवल कुछ मान है जो पैरामीटर के रूप में यहां पारित किया गया है।

+0

मैंने आपके घरों को 'home.cshtml' में 'क्लिकवेन्ट' पर 'अपरिभाषित' के साथ समाप्त होने के साथ समाप्त किया है, यह मेरा कार्य' '** ps: ** डेवलपर कंसोल में यह ठीक काम करता है। – k11k2

+0

क्या आपने अपने घटक में Ngzone आयात किया था? –

0

मैं कोड की जांच कर रहा था, और मुझे सामना करना पड़ा कि ज़ोन शायद आवश्यक नहीं है। यह NgZone के बिना अच्छी तरह से काम करता है।

घटक निर्माता में ऐसा करते हैं:

constructor(....) { 
    window['fncIdentifierCompRef'] = { 
     component = this 
    }; 
} 

और जड़ लिपि में इस प्रयास करें:

<script> 
function theGlobalJavascriptFnc(value) { 
    try { 
    if (!window.fncIdentifierCompRef) { 
     alert('No window.fncIdentifierCompRef); 
     return; 
    } 
    if (!window.fncIdentifierCompRef.component) { 
     alert('No window.fncIdentifierCompRef.component'); 
     return; 
    } 
    window.fncIdentifierCompRef.component.PublicCmpFunc(value); 
    } catch(ex) {alert('Error on Cmp.PublicCmpFunc Method Call')} 
} 
</script> 

यह मेरे लिए काम करता है।

संबंधित मुद्दे