Brief Explanation:
I think you're misunderstanding the intended purpose of a 'view-state' and Spring webflow in general.
Spring Webflow = An xml file that describes a "Sequential" logical flow of states that achieve a single goal (e.g 'Book an airline ticket', 'Gather information for cooking receipes', etc...)
"Sequential" here means that every single state (e.g view-state, action-state, decision-state, end-state) is a SINGLE UNIT of EXECUTION inside Spring webflow. Where each state EXPLICITLY defines what the 'next' state is going to be once it completes execution. For instance,
(view-state A) -> (action-state B) -> (decision-state C) -> (end-state D)
There is no concept of iteration defined with in each state because they are single units of execution. Once a state finishes execution it must go to the next state as defined by the 'transition' tag.
<view-state id="stateA">
<transition to="stateB"/>
</view-state>
Also notice I wrote "Sequential" in quotes because although the flow is sequential (from state -> state)... we can still jump back to any state we wish like so.
(view-state A) -> (action-state B) -> (decision-state C) -> (view-state A)
So...your interpretation of internal view-state iteration does not exist.
Answer to your question:
There are several ways to achieve the 'state' iteration you desire but it sounds like you need a decision-state to delegate the flow based on some flowScope variable. Basically you want to keep track of the num of times you want to execute a particular state then everytime you execute the state you decrement the variable by ( 1 ) and reevaluate it until the num of executions == 0.
Sample flow defined below with comments ( not based on the example code just from your description ).
<!-- define the 'global' flowScope variable that will track the num of times you want to execute the ingredients state -->
<set name="flowScope.numOfTimesToExecuteIngredientsState" value="0" type="java.lang.Integer"/>
<view-state id="basicInfoState" model="basicInfoModel">
<!-- initially goto the decision state and make sure to set the num of execution inside the transition to the 'global' flowScope tracking variable -->
<transition on="save" to="ingredientsIteratorDecisionState">
<!-- assuming ingredients is an initialized Set<Ingredients>... get the size and put inside a flowScope var -->
<set name="flowScope.numOfTimesToExecuteIngredientsState" value="basicInfoModel.getIngredients().size()"/>
</transition>
</view-state>
<decision-state id="ingredientsIteratorDecisionState">
<!-- if # of executions is more than 0 go back to ingredientState otherwise move on to instructionsState -->
<if test="flowScope.numOfTimesToExecuteIngredientsState > 0" then="ingredientsState" else="instructionsState"/>
</decision-state>
<view-state id="ingredientsState">
<transition on="save" to="ingredientsIteratorDecisionState">
<! -- upon a successful save... decrement numOfIngredientsSelected by ( 1 ) -->
<set name="flowScope.numOfTimesToExecuteIngredientsState" value="flowScope.numOfTimesToExecuteIngredientsState - 1"/>
</transition>
</view-state>
Disclaimer: the flow definitions above were not tested. I just wrote it from memory. There might be syntax errors.
You also asked:
Alternatively, is there a way to set a in the webflow.xml that
can be updated in the view #1 jsp form and then evaluated in view #2
without calling a server function? Or is using and output a
possible solution? Or could I use a requestparam?
No. There will always be a call to the server. Why not just deduce the # of recipes from the collection object's size stored on your model?
You could enable SWF the handling of ajax requests and send a requestParam to a transition with no defined 'to=' state. (meaning it will stay in the current view-state) and inside the transition tag do your custom logic (see: How to include a pop-up dialog box in subflow)
but I think this is a design problem. All the values you pass should be in a single http request (and therefore part of your model).