Я очень стараюсь создать что-то похожее на пример велосипедной карты от Salesforce.

У меня есть плитка, список и компонент селектора в иерархии, а затем еще один компонент Registration, который должен функционировать аналогично компоненту деталей в конце.

Проблема в том, что я не могу получить данные для заполнения, как я ожидаю. Вот что я думаю происходит:

  1. List.cmp правильно получает записи из базы данных
  2. Затем List.cmp выполняет итерацию по списку, создавая отдельный tile.cmp для каждого элемента.
  3. Tile.cmp правильно заполняется данными
  4. Tile.cmp создает кнопку
  5. Tile.cmp запускает пользовательское событие и передает выбранный идентификатор вверх по иерархии.
  6. List.cmp правильно получает данные и отправляет другое пользовательское событие с заданным идентификатором.
  7. Selector.cmp правильно получает событие
  8. Селектор.cmp ? пытается поместить значение в selectedEventRegistrationId
  9. Затем Selector.cmp создает Registration.cmp и передает полученный selectedEventRegistrationId как giveneventid
  10. Registration.cmp выполняет @wire getRecord на giveneventid
  11. Registration.cmp должен отображать конкретную информацию о записи.
  12. Отсюда я могу построить то, что мне нужно

Проблема, как я вижу, возникает на шаге 8. Я не могу убедиться, что идентификатор передается так, как я этого хочу. Как видите, я включил много журналов отладки. Вот что я вижу в журнале отладки:

  • Кнопка была нажата
  • Список получил событие, попытается отправить селектору
  • ueventid =
  • a1R3F000001hQT7UAM
  • Селектор получил событие
  • выбранныйEventRegistrationId =
  • TypeError: this.uoEvent.data is undefined

Я заставляю Registration.cmp отображать бит This should show before selecting a tile, а затем исчезать, когда я нажимаю кнопку. Так что я думаю, что это означает, что он ЧТО-ТО получает, верно? Затем я изо всех сил пытаюсь получить то, что я предполагаю, является идентификатором в Registration.cmp и правильно извлекать данные из SF.

Может ли кто-нибудь просмотреть и сказать мне, что я делаю неправильно? А может быть, что у меня все не так и где/как начать сначала?

Я думаю, два моих самых больших вопроса:

  1. Я передаю идентификатор до Selector, а затем до Registration, как я думаю?
  2. Почему при регистрации не получается/отображается запись, которую я хочу?

Я попытался вырезать части кода, которые работают, чтобы общий пост не был таким длинным.


плитка.html

<lightning-button variant="brand" label="Register" title="Primary action" onclick={handleRegister} icon-name="utility:retail_execution" icon-position="left" class="slds-m-left_x-small"></lightning-button>

tile.js

export default class OutreachEventTile extends LightningElement {
    @api uoevent;
    
    handleRegister(){
        console.log("Button was clicked");
        const selectedEvent = new CustomEvent('registerevent', {
            detail: this.uoevent.Id
        });
        this.dispatchEvent(selectedEvent);
    }
}

< Сильный > List.js

handleTileRegistration(event){
    console.log("List received the event, will try to send to selector");
    const uoeventid = event.detail;
    console.log('uoeventid = ');
    console.log(uoeventid);

    //Fire another event that gives the Event ID to the Selector component
    const selectedEvent = new CustomEvent('selectevent', {
        detail: uoeventid,
    });
    this.dispatchEvent(selectedEvent);
}

Селектор.html

<template>
    <div class="wrapper">
    <header class="header">Register</header>
    <section class="content">
        <div class="columns">
        <main class="main" >
            <c-outreach-event-list onselectevent={handleEventRegistrationClick}></c-outreach-event-list>
        </main>
        <aside class="sidebar-second">
            <template if:true={selectedEventRegistrationId}>
                <c-outreach-event-registration giveneventid={selectedEventRegistrationId}></c-outreach-event-registration>
            </template>
            <template if:false={selectedEventRegistrationId}>
                This should show before selecting a tile
                <br/>
                {selectedEventRegistrationId}
            </template>
        </aside>
        </div>
    </section>
    </div>
</template>

Selector.js

import { LightningElement} from 'lwc';

export default class OutreachSelector extends LightningElement {
    selectedEventRegistrationId;

    handleEventRegistrationClick(event){
        console.log("The selector has received the event");
        this.selectedEventRegistrationId = event.detail;
        console.log('selectedEventRegistrationId = ');
        console.log(selectedEventRegistrationId);
    }
}

< Сильный > Registration.html

<template>
    <lightning-card title={cardTitle} icon-name="standard:event">
        <div class = "slds-m-vertical_medium slds-m-left_medium">
            <h1 class="slds-text-heading_small">
                <lightning-formatted-date-time value={startDateTime} year="numeric" month="short" day="2-digit" weekday="long" 
                    hour="2-digit" minute="2-digit" time-zone-name="short">
                </lightning-formatted-date-time>
            </h1>

            <br/>

            <h1 class="slds-text-heading_small">Event Description</h1>
            <p>
                <lightning-formatted-rich-text value={publicDescription} ></lightning-formatted-rich-text>
            </p>

            <br/>

            <h1 class="slds-text-heading_small">Event Location</h1>
            <lightning-formatted-address
                street={streetAddress}
                city={cityAddress}
                province={stateAddress}
                postal-code={zipAddress}
            ></lightning-formatted-address>
        </div>
        
    </lightning-card>
</template>

< Сильный > Registration.js

import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';


const fields  = [
    'UO_Event__c.Name',
    'UO_Event__c.Title__c',
    'UO_Event__c.Public_Title__c',
    'UO_Event__c.Account__c',
    'UO_Event__c.Point_of_Contact__c',
    'UO_Event__c.Activity_Type__c',
    'UO_Event__c.Audience_Type__c',
    'UO_Event__c.Street_Address__c',
    'UO_Event__c.City__c',
    'UO_Event__c.State__c',
    'UO_Event__c.Zip_Code__c',
    'UO_Event__c.Start_Date__c',
    'UO_Event__c.Start_DateTime__c',
    'UO_Event__c.End_Date__c',
    'UO_Event__c.Military_Branch__c',
    'UO_Event__c.Military_Status__c',
    'UO_Event__c.Public_Description__c',
    'UO_Event__c.OwnerId'
];

export default class OutreachEventRegistration extends LightningElement {
    @api giveneventid;

    @wire(getRecord, {recordId: '$giveneventid', fields })
    uoEvent;

    get cardTitle(){
        return this.uoEvent.data.fields.Public_Title__c.value;
    }

    get streetAddress(){
        return this.uoEvent.data.fields.Street_Address__c.value;
    }

    get cityAddress(){
        return this.uoEvent.data.fields.City__c.value;
    }

    get stateAddress(){
        return this.uoEvent.data.fields.State__c.value;
    }

    get zipAddress(){
        return this.uoEvent.data.fields.Zip_Code__c.value;
    }

    get startDate(){
        return this.uoEvent.data.fields.Start_Date__c.value;
    }

    get startDateTime(){
        return this.uoEvent.data.fields.Start_DateTime__c.value;
    }

    get endDate(){
        return this.uoEvent.data.fields.End_Date__c.value;
    }

    get publicDescription(){
        return this.uoEvent.data.fields.Public_Description__c.value;
    }
}
1
Chance 22 Июн 2020 в 23:45
Можете ли вы попробовать изменить событие, чтобы следовать примеру из документации new CustomEvent('selectevent', { detail: { uoeventid: uoeventid } }); Тогда вместо this.selectedEventRegistrationId = event.detail; делать this.selectedEventRegistrationId = event.detail.uoeventid;? Получаете ли вы значение идентификатора на шаге 8 после этого изменения?
 – 
Arthlete
23 Июн 2020 в 00:27
Я не получаю исключения как такового. Я не могу установить selectedEventRegistrationId в селекторе (который является родительским для всех). Оттуда я хочу передать этот идентификатор дочернему компоненту Registration, и это должна быть переменная giveneventid
 – 
Chance
23 Июн 2020 в 00:33
Я попробовал внести изменения, которые вы предложили для деталей{} в List.js, но столкнулся с той же проблемой. selectedEventRegistrationId = [ничего не возвращается в следующей строке], а затем: TypeError: this.uoEvent.data is undefined
 – 
Chance
23 Июн 2020 в 00:42
Хорошо, вы можете попробовать это const uoeventid = JSON.parse(JSON.stringify(event.detail)); вместо const uoeventid = event.detail;?
 – 
Arthlete
23 Июн 2020 в 01:02
Я тоже пробовал это, @arthlete, и он все еще не возвращает значение для selectedEventRegistrationId
 – 
Chance
23 Июн 2020 в 17:21

1 ответ

Лучший ответ

Ваша первоначальная загрузка будет иметь эту ошибку, потому что вы еще не проверяете, заполнены ли данные. Вместо этого используйте getFieldValue:

import { getRecord, getFieldValue } from 'lightning/uiRecordApi';

...

get publicDescription(){
    return getFieldValue(this.uoEvent.data,'UO_Event__c.Public_Description__c');
}

Кроме того, вы должны использовать токены полей вместо простых строк для своих полей.

Все остальное выглядит нормально, насколько я могу судить.


Редактировать:

Токены поля используются для проверки существования поля во время компиляции:

import UOEVENT_PUBLIC_DESCRIPTION_FIELD from '@salesforce/schema/UO_Event__c.Public_Description__c';

Который вы затем можете использовать в своих полях:

Константные поля = [ UOEVENT_PUBLIC_DESCRIPTION_FIELD, ...

И в методе получения:

get publicDescription(){
    return getFieldValue(this.uoEvent.data, UOEVENT_PUBLIC_DESCRIPTION_FIELD);
}

...

2
sfdcfox 23 Июн 2020 в 17:08
Спасибо. Теперь моя карта будет отображаться, но не получит данные от кнопки, как я ожидаю. selectedEventRegistrationId по-прежнему ничего не показывает (наверное, undefined?). Пара вопросов вдогонку, если не возражаете. Что вы подразумеваете под полевыми токенами? И можете ли вы объяснить разницу между операторами возврата, чтобы я понял и не повторял ту же ошибку в будущем, пожалуйста? Еще раз спасибо.
 – 
Chance
23 Июн 2020 в 17:02
1
Добавлено немного о полевых токенах. Разница в типах возвращаемых значений заключается в том, что getFieldValue проверяет нулевые значения и поэтому не выдает ошибку; ваш код предполагает, что объект уже полностью заполнен, что не так, пока метод проводки не вернет данные.
 – 
sfdcfox
23 Июн 2020 в 17:09
Из-за этого карта не заполняется? Как вы думаете, он действительно получает идентификатор с кнопки?
 – 
Chance
23 Июн 2020 в 17:12
Кроме того, поскольку вы используете API getRecord, я думаю, что следующая строка неверна: detail: this.uoevent.Id должно быть detail: this.uoevent.fields.Id.value.
 – 
sfdcfox
23 Июн 2020 в 17:12
1
Итак, мне потребовалась целая вечность, чтобы понять это и понять, о чем вы говорите, и у меня все еще были проблемы. Затем я узнал, что FLS все еще не был установлен для сообщества, это происходило и приводило к поломке результата. Всегда проверяйте ФЛС. Спасибо вам обоим. @Артлет
 – 
Chance
26 Июн 2020 в 18:58