कोणीय 2 में एक घटक के पुन: प्रतिपादन को कैसे बाध्य किया जाए?


181

कोणीय 2 में एक घटक के पुन: प्रतिपादन को कैसे बाध्य किया जाए? डीबग उद्देश्यों के लिए Redux के साथ काम करने के लिए मैं एक घटक को फिर से प्रस्तुत करने के लिए मजबूर करना चाहूंगा, क्या यह संभव है?


"री-रेंडरिंग" से आपका क्या मतलब है। बाइंडिंग अपडेट करें?
गुंटर ज़ोचबॉयर

बस एक त्वरित सवाल है कि आपको फिर से प्रतिपादन करने की आवश्यकता क्यों है?
त्योंग ले

जवाबों:


217

परिवर्तन का पता लगाने के बाद रेंडरिंग होता है। परिवर्तन का पता लगाने के लिए, ताकि घटक संपत्ति मूल्य जो बदल गए हैं, DOM (और फिर ब्राउज़र दृश्य में उन परिवर्तनों को प्रस्तुत करेगा) के लिए प्रचारित हो जाते हैं, यहां कुछ विकल्प दिए गए हैं:

  • ApplicationRef.tick () - Angular 1's के समान ($rootScope.$digest() यानी, पूर्ण घटक वृक्ष की जाँच करें
  • NgZone.run (कॉलबैक) - के समान $rootScope.$apply(callback)- यानी, कोणीय 2 क्षेत्र के अंदर कॉलबैक फ़ंक्शन का मूल्यांकन करें। मुझे लगता है, लेकिन मुझे यकीन नहीं है, कि यह कॉलबैक फ़ंक्शन को निष्पादित करने के बाद पूर्ण घटक ट्री की जाँच करता है।
  • ChangeDetectorRef.detectChanges () - के समान $scope.$digest()- अर्थात, केवल इस घटक और उसके बच्चों की जाँच करें

आप आयात और फिर इंजेक्षन करने की आवश्यकता होगी ApplicationRef, NgZoneया ChangeDetectorRefअपने घटक में।

आपके विशेष परिदृश्य के लिए, मैं अंतिम विकल्प की सिफारिश करूंगा यदि केवल एक घटक बदल गया है।


1
ChangeDetectorRef पर कोई भी कार्य कोड कोणीय 2 के अंतिम संस्करण के लिए? अब मैं एक ऐसी स्थिति का सामना कर रहा हूं, जहां एक नया उपयोगकर्ता बनाने के लिए http के पोस्ट अनुरोध के बाद अद्यतन नहीं किया गया है और फिर सफलता पर मौजूदा पुराने उपयोगकर्ता सूची में नए ऑब्जेक्ट को धकेल दिया जाता है (दृश्य में पुनरावृत्त करने के लिए उपयोग किया जाता है)। काफी अजीब है this is the first time I am facing an update not working in ng2। परिवर्तन का पता लगाने की रणनीति डिफ़ॉल्ट है इसलिए मुझे पता है कि मैंने परिवर्तन का पता लगाने की रणनीति के साथ खिलवाड़ नहीं किया है।
गैरी

1
@ गैरी, आपको एक नया प्रश्न पोस्ट करना चाहिए और आपके घटक और आपके सेवा कोड को शामिल करना चाहिए (आदर्श रूप से, इस मुद्दे को प्रदर्शित करने वाला न्यूनतम प्लंकर शामिल करें)। एक आम समस्या जो मैंने देखी है thisवह POST कॉलबैक में उचित संदर्भ का उपयोग नहीं कर रही है ।
मार्क राजकोक

क्या आप जानते हैं कि जब भी मैं कोई बदलाव करता हूं, तो क्या मैं पाइप को मैन्युअल रूप से ट्रिगर कर सकता हूं? मैंने परिवर्तन का पता लगाने की कोशिश की है, लेकिन पाइप अपडेट नहीं करता है ... मैंने pure:falseपाइप में भी कोशिश की है । यह काम करता है लेकिन यह मेरे उपयोग के मामले के लिए बहुत महंगा (अक्षम) है।
नौ

1
@ नोकोन, मुझे मैन्युअल रूप से पाइप अपडेट को ट्रिगर करने के किसी भी तरीके के बारे में पता नहीं है। जब भी आप किसी अपडेट को ट्रिगर करना चाहते हैं, तो आप एक शुद्ध पाइप का उपयोग कर सकते हैं और ऑब्जेक्ट संदर्भ को बदल सकते हैं। यह पाइप डॉक के "शुद्ध पाइप्स" अनुभाग के तहत चर्चा की गई है । आपके उपयोग के मामले के आधार पर, आप एक पाइप के बजाय एक घटक संपत्ति का उपयोग करना चाह सकते हैं। इस तकनीक की संक्षिप्त चर्चा पाइप्स डॉक के अंत में की गई है।
मार्क राजकोक

1
@ एन-एट, सभी लिंक ठीक हो गए हैं।
मार्क राजकोक

47

tx, मुझे आवश्यक वर्कअराउंड मिला:

  constructor(private zone:NgZone) {
    // enable to for time travel
    this.appStore.subscribe((state) => {
        this.zone.run(() => {
            console.log('enabled time travel');
        });
    });

ज़ोन चल रहा है ।un घटक को फिर से प्रस्तुत करने के लिए मजबूर करेगा


6
इस संदर्भ में appStore क्या है - किस प्रकार का चर और इसका प्रकार? लगता है कि यह देखने योग्य है ... लेकिन मेरा अवलोकन उस घटक के अंदर है, जिसे मैं एक बटन के एक क्लिक पर रिफ्रेश करना चाहता हूं ... और मुझे नहीं पता कि माता-पिता / वर्तमान स्थान से चाइल्ड कंपोनेंट विधि / चर का उपयोग कैसे किया जाए
अब्देली चंदनवाला

28

ChangeDetectorRef दृष्टिकोण

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';

export class MyComponent {

    constructor(private cdr: ChangeDetectorRef) { }

    selected(item: any) {
        if (item == 'Department')
            this.isDepartment = true;
        else
            this.isDepartment = false;
        this.cdr.detectChanges();
    }

}

14

मैं * ngIf का उपयोग करके अपने घटक को फिर से लोड करता हूं।

मेरे कंटेनर के अंदर सभी घटक पूर्ण जीवनचक्र के हुक पर वापस चले जाते हैं।

टेम्पलेट में:

<ng-container *ngIf="_reload">
    components here 
</ng-container>

फिर ts फ़ाइल में:

public _reload = true;

private reload() {
    setTimeout(() => this._reload = false);
    setTimeout(() => this._reload = true);
}

इसके लिए धन्यवाद, @ गुब्बिस! मुझे लगा कि यह काम करना चाहिए, और मेरे पास इसके अलावा सब कुछ था setTimeout()। अब मेरा एक सरल और हल्के समाधान के साथ काम कर रहा है!
LHM

अगर मैं इसे 10000+ बार
बढ़ा

1 बात ध्यान दें - कंटेनर गायब होने और फिर से दिखाई देने से आकार में परिवर्तन हो सकता है और पृष्ठ झिलमिलाहट कर सकता है
ghosh

9

अन्य उत्तर यहां परिवर्तन का पता लगाने वाले चक्रों को ट्रिगर करने के लिए समाधान प्रदान करते हैं जो घटक के दृष्टिकोण को अद्यतन करेगा (जो पूर्ण पुन: रेंडर के समान नहीं है)।

पूर्ण पुन: प्रस्तुत करना, जो घटक को नष्ट कर देगा और पुनर्निमित करेगा (सभी जीवन चक्र हुक और पुनर्निर्माण दृश्य को कॉल करके) का उपयोग करके किया जा सकता है ng-template, ng-containerऔर ViewContainerRefनिम्नलिखित तरीके से:

<div>
  <ng-container #outlet >
  </ng-container>
</div>

<ng-template #content>
  <child></child>
</ng-template>

फिर दोनों के संदर्भ में घटक #outletऔर #contentहम आउटलेट की सामग्री को साफ कर सकते हैं और बच्चे के घटक का एक और उदाहरण डाल सकते हैं:

@ViewChild("outlet", {read: ViewContainerRef}) outletRef: ViewContainerRef;
@ViewChild("content", {read: TemplateRef}) contentRef: TemplateRef<any>;

private rerender() {
    this.outletRef.clear();
    this.outletRef.createEmbeddedView(this.contentRef);
}

इसके अतिरिक्त प्रारंभिक सामग्री AfterContentInitहुक पर डाली जानी चाहिए :

ngAfterContentInit() {
    this.outletRef.createEmbeddedView(this.contentRef);
}

पूर्ण कार्य समाधान यहां पाया जा सकता है https://stackblitz.com/edit/angular-component-rerender


1

ChangeDetectorRef.detectChanges()आमतौर पर ऐसा करने का सबसे केंद्रित तरीका है। ApplicationRef.tick()आमतौर पर एक स्लेजहैमर दृष्टिकोण के बहुत अधिक है।

उपयोग करने के लिए ChangeDetectorRef.detectChanges(), आपको अपने घटक के शीर्ष पर इसकी आवश्यकता होगी:

import {  ChangeDetectorRef } from '@angular/core';

... तो, आमतौर पर आप उर्फ ​​है कि जब आप इसे इस तरह अपने निर्माता में इंजेक्ट करते हैं:

constructor( private cdr: ChangeDetectorRef ) { ... }

फिर, उपयुक्त स्थान पर , आप इसे इस तरह कहते हैं:

this.cdr.detectChanges();

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.