Правильный способ перехода со страницы «Список» на страницу «Подробности» (наоборот) [дубликат]

Js - однопоточная.

Браузер можно разделить на три части:

1) Event Loop

2 ) Web API

3) Очередь событий

Событие Loop запускается вечно, т. Е. Тип бесконечного цикла. Очередь ожидания - это то, где вся ваша функция нажимается на какое-либо событие (пример: нажмите) this один за другим выполняется в очереди и помещается в цикл «Событие», который выполняет эту функцию и подготавливает ее для следующего после первого запуска. Это означает, что выполнение одной функции не начинается до тех пор, пока функция, перед которой она в очереди не будет выполнена цикл событий.

Теперь давайте подумаем, что мы поставили две функции в очереди, чтобы получить данные с сервера, а другой использует эти данные. Мы сначала нажали функцию serverRequest () в очереди, а затем применили функцию Data () , Функция serverRequest переходит в цикл событий и делает вызов на сервер, так как мы никогда не знаем, сколько времени потребуется для получения данных с сервера, поэтому ожидается, что этот процесс займет много времени, и поэтому мы заняли наш цикл событий, тем самым повесив нашу страницу, вот где Web API входит в эту роль, он принимает эту функцию из цикла событий и обращается к серверу, создающему цикл событий, так что мы можем выполнить следующую функцию из очереди. Следующая функция в очереди - useData (), которая идет в цикле, но из-за отсутствия данных отходы и выполнение следующей функции продолжаются до конца очереди (это называется Async-вызовом, то есть мы можем сделать что-то еще, пока не получим данные)

Предположим, что наша функция serverRequest () имела оператор возврата в код, когда мы возвращаем данные с сервера Web API, будет выталкивать его в очередь в конце очереди. По мере того, как он заканчивается в очереди, мы не можем использовать его данные, поскольку в нашей очереди нет функции, чтобы использовать эти данные. Таким образом, невозможно вернуть что-то из Async Call.

Таким образом, решение этой проблемы callback или обещают .

A Изображение из одного из ответов здесь, правильно объясняет использование обратного вызова ... Мы (функция, использующая данные, возвращаемые с сервера), чтобы вызвать вызывающий сервер.

 function doAjax(callbackFunc, method, url) {
  var xmlHttpReq = new XMLHttpRequest();
  xmlHttpReq.open(method, url);
  xmlHttpReq.onreadystatechange = function() {

      if (xmlHttpReq.readyState == 4 && xmlHttpReq.status == 200) {
        callbackFunc(xmlHttpReq.responseText);
      }


  }
  xmlHttpReq.send(null);

}

В моем коде он называется

function loadMyJson(categoryValue){
  if(categoryValue==="veg")
  doAjax(print,"GET","http://localhost:3004/vegetables");
  else if(categoryValue==="fruits")
  doAjax(print,"GET","http://localhost:3004/fruits");
  else 
  console.log("Data not found");
}

Прочитайте здесь новые методы в ECMA (2016/17) для создания асинхронного вызова (@Felix Kling Answer сверху) https://stackoverflow.com/a/14220323/7579856

23
задан BalusC 31 May 2015 в 16:09
поделиться

2 ответа

Какое правильное использование области сеанса

Используйте его только для данных с областью сеанса, и ничего больше. Например, вошедший в систему пользователь, его настройки, выбранный язык и т. Д.

См. Также:


И каждый раз, когда я посещаю страницу, список продуктов будет создан из последних записей в базе данных. Как я могу справиться с этим?

Обычно для этого используется область запроса или представления. Загрузка списка должна выполняться по методу @PostConstruct. Если страница не содержит <h:form>, то область запроса будет прекрасной. Объект, обработанный представлением, будет вести себя как область запроса, если в любом случае нет <h:form>.

Все ссылки «Просмотреть продукт» и «редактировать товар», которые только извлекают информацию (т.е. идемпотент), должны быть просто GET <h:link> / <h:button>, в которые вы проходите идентификатор объекта как параметр запроса по <f:param>.

Все ссылки «delete product» и «save product» / кнопки, которые будут обрабатывать информацию (т.е. не-идемпотент), должны выполнять POST с помощью <h:commandLink> / <h:commandButton> (вы не хотите, чтобы они были заклассифицированы / searchbot-indexable!). Это, в свою очередь, требует <h:form>. Чтобы сохранить данные для валидаций и ajax-запросов (так что вам не нужно перезагружать / preinitialize сущность при каждом запросе), компонент должен быть предпочтительно областью видимости.

Обратите внимание, что в каждом представлении вы должны иметь отдельный компонент, а также обратите внимание, что эти beans необязательно должны ссылаться друг на друга.

Итак, с учетом этого объекта «продукта» :

@Entity
public class Product {

    @Id
    private Long id;
    private String name;
    private String description;

    // ...
}

И этот «сервисный сервис» EJB:

@Stateless
public class ProductService {

    @PersistenceContext
    private EntityManager em;

    public Product find(Long id) {
        return em.find(Product.class, id);
    }

    public List<Product> list() {
        return em.createQuery("SELECT p FROM Product p", Product.class).getResultList();
    }

    public void create(Product product) {
        em.persist(product);
    }

    public void update(Product product) {
        em.merge(product);
    }

    public void delete(Product product) {
        em.remove(em.contains(product) ? product : em.merge(product));
    }

    // ...
}

Вы можете использовать этот «просмотр продуктов» на /products.xhtml:

<h:dataTable value="#{viewProducts.products}" var="product">
    <h:column>#{product.id}</h:column>
    <h:column>#{product.name}</h:column>
    <h:column>#{product.description}</h:column>
    <h:column>
        <h:link value="Edit" outcome="/products/edit">
            <f:param name="id" value="#{product.id}" />
        </h:link>
    </h:column>
</h:dataTable>
@Named
@RequestScoped
public class ViewProducts {

    private List<Product> products; // +getter

    @EJB
    private ProductService productService;

    @PostConstruct
    public void init() {
        products = productService.list();
    }

    // ...
}

И вы можете получить этот «продукт редактирования» на /products/edit.xhtml:

<f:metadata>
    <f:viewParam name="id" value="#{editProduct.product}" 
        converter="#{productConverter}" converterMessage="Unknown product, please use a link from within the system."
        required="true" requiredMessage="Bad request, please use a link from within the system."
    />
</f:metadata>

<h:messages />

<h:form rendered="#{not empty editProduct.product}>
    <h:inputText value="#{editProduct.product.name}" />
    <h:inputTextarea value="#{editProduct.product.description}" />
    ...
    <h:commandButton value="save" action="#{editProduct.save}" />
</h:form>
@Named
@ViewScoped
public class EditProduct {

    private Product product; // +getter +setter

    @EJB
    private ProductService productService;

    public String save() {
        productService.save(product);
        return "/products?faces-redirect=true";
    }

    // ...
}

И этот преобразователь для <f:viewParam> для «edit product»:

@Named
@RequestScoped
public class ProductConverter implements Converter {

    @EJB
    private ProductService productService;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }

        try {
            Long id = Long.valueOf(value);
            return productService.find(id);
        } catch (NumberFormatException e) {
            throw new ConverterException("The value is not a valid Product ID: " + value, e);
        }
    }

    @Override    
    public String getAsString(FacesContext context, UIComponent component, Object value) {        
        if (value == null) {
            return "";
        }

        if (value instanceof Product) {
            Long id = ((Product) value).getId();
            return (id != null) ? String.valueOf(id) : null;
        } else {
            throw new ConverterException("The value is not a valid Product instance: " + value);
        }
    }

}

См. также:

49
ответ дан Community 27 August 2018 в 18:58
поделиться

В качестве небольшого улучшения, рекомендуемого BalusC, иногда вы можете удалить часть required / requiredMessage из <f:viewParam> вашего экрана «details» и вместо этого использовать условную визуализацию формы редактирования (поскольку BalusC сделал ) с обратным условием для рекомендации конкретной ссылки для экрана «список / мастер» или даже использовать viewAction, который будет проверять параметр и принудительно перенаправлять его в этот список.

0
ответ дан bruno 27 August 2018 в 18:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: