简体   繁体   English

从 Visualforce 页面在 Controller 中设置值花费的时间太长

[英]Setting a value in Controller from Visualforce Page is taking too long

I'm using Visualforce Page to display some selection fields, and based on the selections I'm updating my list.我正在使用 Visualforce Page 来显示一些选择字段,并根据我正在更新我的列表的选择。

<apex:form>
    <div class="map-controls">
        <div class="map-selects">
            <apex:selectList value="{!state}" multiselect="false" size="1">
                <apex:selectOptions value="{!states}"></apex:selectOptions>
                <apex:actionSupport event="onchange" rerender="countyList" />
            </apex:selectList>

            <apex:selectList value="{!county}" multiselect="false" size="1" id="countyList">
                <apex:selectOptions value="{!counties}"></apex:selectOptions>
            </apex:selectList>
        </div>

        <div class="map-search">
            <apex:commandButton value="Search" action="{!test}" rerender="productlistpanel" status="status" />
        </div>

        <div class="radio-btns">
            <apex:selectRadio value="{!type}">
                <apex:selectOptions value="{!types}" />
            </apex:selectRadio>
        </div>
    </div>
</apex:form>

Basically what I'm trying to do here is, when user selects the State, County and Type upon clicking the commandButton, the product list will be rendered.基本上我在这里要做的是,当用户在单击命令按钮时选择 State、县和类型时,将呈现产品列表。

<apex:outputPanel id="productlistpanel">
    <div class="splide" role="group">
        <div class="splide__track">
            <ul class="splide__list">
                <apex:repeat value="{!products}" var="productKey" id="theRepeat">
                    <!-- REPEAT CONTENT -->
                </apex:repeat>
            </ul>
        </div>
    </div>
    
    <script>
    document.dispatchEvent(new CustomEvent("splideTest", { "detail": 'TEST' }));                    
    </script>
</apex:outputPanel>

And this is my controller.这是我的 controller。

public List<SelectOption> getTypes() {
    RecordTypeInfo TYPE1 = Schema.SObjectType.Product2.getRecordTypeInfosByDeveloperName().get('TYPE1');
    RecordTypeInfo TYPE2 = Schema.SObjectType.Product2.getRecordTypeInfosByDeveloperName().get('TYPE2');

    List<SelectOption> options = new List<SelectOption>();
    options.add(new SelectOption(TYPE1.getRecordTypeId(), 'TYPE1'));
    options.add(new SelectOption(TYPE2.getRecordTypeId(), 'TYPE2'));

    return options;
}

public List<SelectOption> getStates() {
    List<SelectOption> options = new List<SelectOption>();
    options.add(new SelectOption('All', 'All'));

    List<State__c> states = [SELECT Id, 
                                Name
                            FROM State__c];

    for (State__c s : states) {
        options.add(new SelectOption(s.Name, s.Name));
    }

    return options;
}

public List<SelectOption> getCounties() {
    List<SelectOption> options = new List<SelectOption>();
    options.add(new SelectOption('All', 'All'));

    List<County__c> counties = new List<County__c>();

    if (state != null && state != 'ALL') {
        counties = [SELECT Id, 
                            State__c, 
                            Name
                    FROM County__c
                    WHERE State__r.Name = :state];
    }

    for (County__c c : counties) {
        options.add(new SelectOption(c.Name, c.Name));
    }

    return options;
}

public PageReference test() {
    return null;
}

public String state { get; set; }

public String county { get; set; }

public String type { get; set; }

public Map<Id, WRAPPER> productList { get; set; }

public Map<Id, WRAPPER> getProducts() {
    try {
        // CREATE QUERY
        query += String.isNotBlank(state) && state != 'ALL' ? ' AND State__c = \'' + state + '\'' : '';
        query += String.isNotBlank(county) && county != 'ALL' ? ' AND County__c = \'' + county + '\'' : '';
        query += String.isNotBlank(type)  ? ' AND RecordTypeId = \'' + type + '\'' : '';
        query += ' ORDER BY Name ASC';

        System.debug('query ' + query);
        List<Product2> productList = (List<Product2>)database.query(query);

        for (Product2 prod : productList) {
            // CREATE LIST
        }

        return returnMap;
    } catch (Exception ex) {
        ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.Error, ex.getMessage());
        ApexPages.addMessage(msg);
        return null;
    }
}

My problem is when I select the type and hit Search;我的问题是当我输入 select 并点击搜索时; the type is not available right away.该类型无法立即使用。 I can see the rerender is being executed and at the logs I see that type is not saved.我可以看到正在执行重新渲染,并且在日志中我看到该类型未保存。 I have to click Search button again to see the Type selected as I wanted it to be.我必须再次单击“搜索”按钮才能看到我希望选择的类型。

I usually use Lightning Web Component and I don't deal with this kind of problem but unfortunately, I have to use VF Page for this implementation.我通常使用 Lightning Web 组件,我不处理此类问题,但不幸的是,我必须使用 VF Page 来实现此实现。

I could not locate any work-around so far, I tried to understand the delay, but it seems like it is not a common issue.到目前为止我找不到任何解决方法,我试图了解延迟,但这似乎不是一个常见问题。 I assume it is a design issue on my end.我认为这是我的设计问题。 I couldn't locate why setting the value is not fast enough.我找不到为什么设置值不够快。

Does that happen to you, or do you have any suggestions for it?你有没有遇到过这种情况,或者你有什么建议吗?

You could cheat, write it in LWC and then use "Lightning Out" to display it.你可以作弊,将它写在 LWC 中,然后使用“Lightning Out”来显示它。 Saves the hassle of eventually rewriting it;)省去了最终重写它的麻烦;)

I suspect part of it is that only 1st picklist has apex:actionSupport .我怀疑部分原因是只有第一个选择列表具有apex:actionSupport

You swallow the exception (maybe there's an issue with the query) and use addMessage - but for it to truly show you need <apex:pageMessages id="messages" /> tag and then add it to your rerender ( rerender="productlistpanel,messages" )您吞下异常(也许查询有问题)并使用addMessage - 但要真正显示您需要<apex:pageMessages id="messages" />标记,然后将其添加到您的重新渲染( rerender="productlistpanel,messages"

Your "type" picklist radio is the only one without fallback "ALL".您的“类型” 选择列表 收音机是唯一没有后备“全部”的收音机。 I suspect in UI it apppears to have type1 selected as 1st entry but really the value is null because you didn't initalise it in controller?我怀疑在 UI 中似乎将 type1 选择为第一个条目,但实际上该值是 null,因为您没有在 controller 中初始化它? See if it behaves better if you explicitly set it in constructor for example.例如,如果您在构造函数中明确设置它,看看它是否表现得更好。

Risko of soql injection (could use bind variables, even in dynamic soql), you could read about <apex:actionRegion> for such partial form submits. soql 注入的 Risko(可以使用绑定变量,即使在动态 soql 中),您可以阅读有关<apex:actionRegion>的此类部分表单提交。 Shameless plug: https://salesforce.stackexchange.com/a/22216/799无耻插件: https://salesforce.stackexchange.com/a/22216/799

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM