11

मैं कोणीय 2 के लिए नया हूं और मुझे एसिंक http अनुरोध और इंटरपोलेशन के साथ बाध्यकारी समस्या का सामना करना पड़ रहा है।कोणीय 2 - एसिंक http अनुरोध

यहाँ मेरी घटक है:

@Component({ 
    selector: 'info', 
    template: `<h1>{{model.Name}}</h1>` 
}) 
export class InfoComponent implements OnInit { 

    model: any; 

    constructor(
     private _service: BackendService 
    ) { } 

    ngOnInit() { 
     if (this.model == null) { 
      this._service.observableModel$.subscribe(m => this.model = m); 
      this._service.get(); 
     }  
    } 
} 

जब टेम्पलेट प्रदान की गई है मैं कोई त्रुटि मिलती है क्योंकि "मॉडल" अभी तक सेट नहीं है।

मैं इस बहुत बदसूरत हैक साथ समस्या हल:

@Component({ 
    selector: 'info', 
    template: ` 
    <template ngFor #model="$implicit" [ngForOf]="models | async"> 
    <h1>{{model.Name}}</h1> 
    </template> 
    ` 
}) 
export class NeadInfoComponent implements OnInit { 

    models: Observable<any>; 

    constructor(
     private _service: BackendService 
    ) { } 

    ngOnInit() { 
     if (this.models == null) { 
      this._service.observableModel$.subscribe(m => this.models = Observable.of([m])); 
      this._service.get(); 
     }  
    } 
} 

मेरा प्रश्न है: मेरे http कॉल पूर्ण होने तक कैसे टेम्पलेट प्रतिपादन को स्थगित करने या कैसे बाध्यकारी बिना टेम्पलेट में सीधे "मॉडल" मूल्यों को जोड़ एक और घटक के लिए?

धन्यवाद!

उत्तर

12

आप अपने सर्वर से एक वस्तु लौट रहे हैं, तो आप उपयोग कर सकते हैं safe navigation (previously "Elvis") operator (?।) अपने खाके में:

@Component({ 
    selector: 'info', 
    template: `<h1>{{model?.Name}}</h1>` 
}) 
export class InfoComponent implements OnInit { 
    model: any; 
    constructor(private _service: BackendService) { } 

    ngOnInit() { 
     this._service.getData().subscribe(m => this.model = m); 
     // getData() looks like the following: 
     // return this._http.get('....') // gets JSON document 
     //  .map(data => data.json()); 
    } 
} 

एक काम plunker के लिए this answer देखें।

+1

धन्यवाद मार्क! एल्विस ने चाल की! लेकिन मैं अभी तक प्रवाह प्रस्तुत नहीं समझता। घटक गुणों में कोई भी बदलाव होने पर हर बार टेम्पलेट प्रस्तुत किया जाता है? –

+2

@ टोनीएलेक्सेंडरहेल्ड, कोणीय परिवर्तन का पता लगाने (जो हर घटना के बाद चलता है) के दौरान, डिफ़ॉल्ट रूप से, आपके सभी दृश्य/टेम्पलेट बाइंडिंग गंदे चेक किए जाते हैं, जिसका अर्थ है कि उन्हें परिवर्तनों के लिए चेक किया गया है। जब सर्वर से डेटा लौटाता है, तो यह एक घटना है, इसलिए पहचान का पता चलता है। 'model.Name' गंदे चेक किया गया है और पाया गया है, इसलिए कोणीय डीओएम अपडेट करता है। कोणीय ब्राउज़र पर नियंत्रण लौटने के बाद, यह डीओएम परिवर्तन को देखता है और जो स्क्रीन पर हम देखते हैं उसे अद्यतन करता है। –

+0

धन्यवाद @MarkRajcok! अब यह स्पष्ट है। –

0

इस चर्चा में कुछ रणनीतियों को सूचीबद्ध https://github.com/angular/angular/issues/6674#issuecomment-174699245

सवाल कई प्रभाव पड़ता है। कुछ मामलों में, अवलोकनों को ढांचे के बाहर प्रबंधित किया जाना चाहिए।

ए से पहले आपको bootstrap

बी बूटस्ट्रैप तो शीर्ष स्तर घटक को वस्तु पार करने से पहले सभी observables स्कैन सभी observables स्कैन कर सकते हैं।

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

डी आप उपयोग कर रहे हैं | तो async यह केवल शीर्ष स्तर पर इस्तेमाल किया जाना चाहिए अगर आप .subscribe का उपयोग कर की तरह नहीं लग रहा है, लेकिन आप वास्तव में सिर्फ .subscribe उपयोग करना चाहिए।

ई। यदि आप हर जगह एसिंक का उपयोग कर रहे हैं तो आप वास्तव में क्या कर रहे हैं वे अवलोकनों को प्रतिपादित करने पर नियंत्रण में बदलाव कर रहे हैं जिसका अर्थ है कि हम कोणीय 1 दिनों में कैस्केडिंग परिवर्तनों में वापस आ गए हैं ताकि आपको सी को करने की आवश्यकता हो, डी, बी, या एक

ChangeDetectionStrategy पल में काम करने लगता है। आप घटक को पृथक के रूप में सेट कर देंगे।

हम भी ngOnInit जीवन चक्र हुक का उपयोग परिवर्तन का पता लगाने के पेड़ से घटक को दूर कर सकते हैं। आपको इसे चलाने की आवश्यकता होगी .ref.detach(); जहां रेफरी ChangeDetectorRef

के माध्यम से
ngOnInit() { 
    this.ref.detach(); 
    } 
    makeYourChanges() { 
    this.ref.reattach(); // attach back to change detector tree 

    this.data.value = Math.random() + ''; // make changes 

    this.ref.detectChanges(); // check as dirty 

    this.ref.detach(); // remove from tree 
    // zone.js triggers changes 
    } 

ChangeDetectorRef

इंजेक्ट किया जाता है तुम भी zone.js शामिल नहीं कर सकते और मैन्युअल रूप से सभी परिवर्तनों को नियंत्रित करते हैं। तुम भी zone.js के बाहर एक ऑपरेशन को चलाने के लिए तो यह चांस को गति प्रदान करने कोणीय नहीं बताएंगे NgZone इंजेक्षन कर सकते हैं। उदाहरण के लिए,

// this example might need a refactor to work with rxjs 5 
export class Timeflies { 
    pos = 'absolute'; 
    color = 'red'; 
    letters: LetterConfig[]; 
    constructor(
    private service: Message, 
    private el: ElementRef, 
    private zone: NgZone) { 

    } 
    ngOnInit() { 
    // initial mapping (before mouse moves) 
    this.letters = this.service.message.map(
     (val, idx) => ({ 
     text: val, 
     top: 100, 
     left: (idx * 20 + 50), 
     index: idx 
     }) 
    ); 
    this.zone.runOutsideAngular(() => { 
     Observable 
     .fromEvent(this.el.nativeElement, 'mousemove') 
     .map((e: MouseEvent) => { 
      //var offset = getOffset(this.el); 

      // subtract offset of the element 
      var o = this.el.nativeElement.getBoundingClientRect(); 

      return { 
      offsetX: e.clientX - o.left, 
      offsetY: e.clientY - o.top 
      }; 
     }) 
     .flatMap(delta => { 
      return Observable 
      .fromArray(this.letters 
       .map((val, index) => ({ 
       letter: val.text, 
       delta, 
       index 
       }))); 
     }) 
     .flatMap(letterConfig => { 
      return Observable 
      .timer((letterConfig.index + 1) * 100) 
      .map(() => ({ 
       text: letterConfig.letter, 
       top: letterConfig.delta.offsetY, 
       left: letterConfig.delta.offsetX + letterConfig.index * 20 + 20, 
       index: letterConfig.index 
      })); 
     }) 
     .subscribe(letterConfig => { 
      // to render the letters, put them back into app zone 
      this.zone.run(() => this.letters[letterConfig.index] = letterConfig); 
     }); 

    });//zone 
    } 
} 
संबंधित मुद्दे