मेरे पास TabChanged नामक एक ईवेंट एक्शन वाला एक कस्टम घटक है। मेरे रेजर पेज में मैंने इसका संदर्भ इस प्रकार सेट किया है:

<TabSet @ref="tabSet">
 ...
</TabSet>

@code {
    private TabSet tabSet;   
    ...
}

OnAfterRenderAsync विधि में मैं ईवेंट के लिए एक हैंडलर असाइन करता हूं:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if(firstRender)
    {
        tabSet.TabChanged += TabChanged;
    }       
}

पहली बार जब पृष्ठ प्रस्तुत होता है तो मुझे एक System.NullReferenceException: ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट की आवृत्ति पर सेट नहीं होता त्रुटि मिलती है।

अगर मैं बाद के रेंडरर्स का उपयोग करने के लिए स्विच करता हूं तो यह ठीक काम करता है:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if(!firstRender)
    {
        tabSet.TabChanged += TabChanged;
    }       
}

लेकिन निश्चित रूप से यह मैला है और मैं कई ईवेंट हैंडलर को फायर कर दूंगा क्योंकि वे रेंडरर्स के दौरान ढेर हो जाते हैं।

मैं संदर्भ को एक बार और पहली बार प्रस्तुत करने पर कैसे निर्दिष्ट कर सकता हूं? मैं बताए गए दस्तावेज़ों का अनुसरण कर रहा हूं यहां

संपादित करें

यहाँ TabSet.razor फ़ाइल है:

@using Components.Tabs

<!-- Display the tab headers -->
<CascadingValue Value="this">
    <ul class="nav nav-tabs">
        @ChildContent
    </ul>
</CascadingValue>

<!-- Display body for only the active tab -->
<div class="nav-tabs-body" style="padding:15px; padding-top:30px;">
    @ActiveTab?.ChildContent
</div>

@code {

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    public ITab ActiveTab { get; private set; }

    public event Action TabChanged;


    public void AddTab(ITab tab)
    {
        if (ActiveTab == null)
        {
            SetActiveTab(tab);
        }
    }

    public void RemoveTab(ITab tab)
    {
        if (ActiveTab == tab)
        {
            SetActiveTab(null);
        }
    }

    public void SetActiveTab(ITab tab)
    {
        if (ActiveTab != tab)
        {
            ActiveTab = tab;
            NotifyStateChanged();
            StateHasChanged();
        }
    }

    private void NotifyStateChanged() => TabChanged?.Invoke();

}

TabSet Tab.razor का भी उपयोग करता है:

@using Components.Tabs
@implements ITab

<li>
    <a @onclick="Activate" class="nav-link @TitleCssClass" role="button">
        @Title
    </a>
</li>

@code {
    [CascadingParameter]
    public TabSet ContainerTabSet { get; set; }

    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }


    private string TitleCssClass => ContainerTabSet.ActiveTab == this ? "active" : null;

    protected override void OnInitialized()
    {
        ContainerTabSet.AddTab(this);
    }

    private void Activate()
    {
        ContainerTabSet.SetActiveTab(this);
    }
}

और ITab.cs इंटरफ़ेस

using Microsoft.AspNetCore.Components;

namespace PlatformAdmin.Components.Tabs
{
    public interface ITab
    {
        RenderFragment ChildContent { get;  }

        public string Title { get; }
    }
}

यह स्टीव सैंडर्सन के उदाहरण से लिया गया है जो यहां मिले हैं।

2 संपादित करें

यहां डिबगर दिखा रहा है कि टैबसेट पहले रेंडर पर शून्य है:

enter image description here

और अतिरिक्त प्रस्तुतकर्ताओं पर शून्य नहीं:

enter image description here

14
INNVTV 13 नवम्बर 2019, 04:02
मैंने आपको कोड देने की कोशिश की, लेकिन if(firstRender) { tabSet.TabChanged += TabChanged; } का उपयोग करते समय मुझे शून्य अपवाद नहीं मिला। क्या TabChanged एक प्रतिनिधि है? क्या आप कृपया हमें पुन: पेश करने का कोई तरीका दिखा सकते हैं?
 – 
itminus
13 नवम्बर 2019, 07:45
इटमिनस के परीक्षण के लिए धन्यवाद। मैंने TabSet घटक फ़ाइलों को शामिल करने के लिए अपना प्रश्न अपडेट किया। इसे यहां स्टीव सैंडर्सन के उदाहरण से लिया गया है: gist.github.com/SteveSandersonMS/… लेकिन मैं घटना को जोड़ा।
 – 
INNVTV
13 नवम्बर 2019, 08:22
मैं आपके कोड का उपयोग करके ब्लेज़र क्लाइंट-साइड प्रोजेक्ट और ब्लेज़र सर्वर-साइड प्रोजेक्ट दोनों बनाता हूँ। हालांकि, यह मेरे लिए काफी अच्छा काम करता है। स्क्रीनशॉट देखें। मुझे नहीं पता कि क्या कमी है?
 – 
itminus
13 नवम्बर 2019, 10:35
यकीन भी नहीं होता। मैंने इसे फिर से चलाया और अपने प्रश्न को पहले और अतिरिक्त दोनों रेंडरर्स के दौरान डिबगर दिखाते हुए स्क्रीनशॉट के साथ अपडेट किया। टैबसेट पहले प्रस्तुत करने के बाद शून्य है लेकिन अगले पर शून्य नहीं है!
 – 
INNVTV
13 नवम्बर 2019, 17:42
क्या आपका <TabSet @ref="tabSet"> अंदर है और if (?
 – 
dani herrera
14 नवम्बर 2019, 10:29

3 जवाब

सबसे बढ़िया उत्तर

जैसा कि Dani Herrera ने टिप्पणियों में बताया है, यह घटक के if/else कथन के साथ होने के कारण हो सकता है और वास्तव में वह था। पहले मेरे पास घटक छिपा हुआ था यदि कोई वस्तु शून्य थी:

@if(Account != null)
{
    <TabSet @ref="tabSet">
     ...
    </TabSet>
}

मैंने इसे संक्षिप्तता के लिए छोड़ दिया और गलत धारणा बना ली कि मुद्दा सशर्त नहीं था। मैं बहुत गलत था क्योंकि पहली बार प्रस्तुत करना वस्तु शून्य है और इसलिए घटक मौजूद नहीं है! तो वहां सावधान रहें। मैंने अपने सशर्त को घटक के भीतर अनुभागों में ले जाकर इसे हल किया:

<TabSet @ref="tabSet">
    @if(Account != null)
    {
        <Tab>
         ...
        </Tab>
        <Tab>
         ...
        </Tab>
    }
</TabSet>
7
ViRuSTriNiTy 5 अगस्त 2020, 15:40

पहले रेंडर में, कंपोनेंट को रेंडर किया जाता है। पहले रेंडर के बाद, रेफरेंस ऑब्जेक्ट कंपोनेंट को संदर्भित करता है। तो, पहली बार, घटक का रेफरी शून्य है (रेफरी नहीं)। अधिक विवरण के लिए, ब्लेज़र का दस्तावेज़ यहां

टैबसेट वैरिएबल केवल घटक के रेंडर होने के बाद ही पॉप्युलेट होता है और इसके आउटपुट में TabSet एलिमेंट शामिल होता है। उस बिंदु तक, संदर्भ के लिए कुछ भी नहीं है। घटक के रेंडरिंग समाप्त होने के बाद घटकों के संदर्भों में हेरफेर करने के लिए, OnAfterRenderAsync या OnAfterRender विधियों का उपयोग करें।

1
Nguyễn Văn Biên 13 नवम्बर 2019, 19:48
1
शायद आप सही हैं लेकिन दस्तावेज़ यह बताते हैं कि संदर्भ उपलब्ध होना चाहिए OnAfterRender या OnAfterRenderAsync जैसा कि मेरे पास है और यह नहीं बताता कि अगर फर्स्टरेंडर सत्य है तो वे अनुपलब्ध होंगे। मैं देखने के लिए थोड़ा और खोदूंगा।
 – 
INNVTV
13 नवम्बर 2019, 22:59
ऑनआफ्टररेंडर को दो बार बुलाया जाता है।
 – 
Nguyễn Văn Biên
14 नवम्बर 2019, 16:33

मेरे मामले में यह ऑब्जेक्ट को इनिशियलाइज़ करके हल किया जाता है

पूर्व: निजी टैबसेट टैबसेट = नया टैबसेट ();

0
Mohamed Omera 5 मई 2021, 16:03