Все советы здесь велики и актуальны, но я бы хотел предложить другое решение. Проблема, которая здесь возникает, определенно является общей схемой, поэтому я думаю, что гораздо лучше просто написать собственный интерфейс для таких обновлений и придерживаться его внутри редукторов, а также использовать одну функцию для глубокого обновления внутри всех ваших редукторов.
Например, я создал библиотеку , где я попытался решить эту проблему следующим образом: я получаю тип модуля (так называемый «тайл»), функцию для выполнения операций ( как асинхронный, так и синхронизированный) и желаемое вложение на основе переданных параметров. Итак, для вашего случая это будет что-то вроде:
import { createSyncTile } from 'redux-tiles';
const uiTile = createSyncTile({
type: ['ui', 'elements'],
fn: ({ params }) => params,
// type will be `notificationBar`
nesting: ({ type }) => [type],
});
И это все - оно будет корректно обновляться при произвольной вложенности. Кроме того, плитка предоставляет селекторы, поэтому вам не нужно беспокоиться о том, где именно находятся данные, вы можете просто использовать их. Поэтому я не хочу сказать, что это лучшее решение, но идея довольно проста - не бойтесь написать собственную реализацию, а затем просто используйте фабрику для решения этой проблемы.
Вот краткое изложение. У вас есть класс ActionForm
, скажем MyForm
:
<form-bean name="myForm" type="myapp.forms.MyForm"/>
У вас есть класс Action
, скажем MyAction
:
<action path="/insert" type="myapp.actions.MyAction" name="myForm"
input="/insert.jsp" validate="true" />
<forward name="success" path="/insertDone.jsp"/>
</action>
"name "в действии" относится к "имени" в форме bean. Потому что у вас есть validate = "true"
ваш ActionForm
класс MyForm
должен определять метод validate ()
, который будет автоматически вызываться:
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if ((username==null) || (username.length() < 1))
errors.add("username", new ActionError("error.username.required"));
return errors;
}
Если он возвращает пустой объект ActionErrors, Struts переходит для вызова MyAction.execute (). В противном случае Struts отображает /insert.jsp (потому что это введенный вами input = parm) и расширяет тег html.errors для отображения ваших ошибок из ActionErrors.
Вот один: //struts.apache.org/1.3.5/struts-taglib/apidocs/org/apache/struts/taglib/html/package-summary.html#package_description
Here I'm assuming Struts 1. I don't know if it has changed for Struts 2.
You can put an errors.header and errors.footer into your message resources file:
errors.header=<h3><font color="red">Errors:</font></h3><ul>
errors.footer=</ul>
The header and footer are displayed only if the ActionErrors object has any errors in it.
In your Action class, do this:
ActionErrors errors = new ActionErrors();
if (badInput) {
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.bad.input", badString); // key in messages resource file
// badString will replace {0} in message
}
Then before returning:
saveErrors(request, errors);
In your messages resource file:
error.bad.input=<li>Bad input: '{0}' is invalid.</li>
Now when the
tag is processed, it will turn into:
<h3><font color="red">Errors:</font></h3><ul>
<li>Bad input: 'xxyyzzz' is invalid.<li>
</ul>