We just saw how one component can call another and that the other component will appear in place of the one calling it. How do we give back control to the caller or return a result? The method
answer: performs this task. It takes an object that we want to return as a parameter.
Let’s demonstrate how to use
answer:. We will add two buttons to the interface of the
ToDoItemView: one for cancelling the edit and one to return the modified item. Note that in one case we use a normal
submitButton, and in the other case we use
Pay attention since the cancel button looks exactly the same as a submit button, but it avoids processing the input callbacks of the form that would modify our model. This means we don’t need to copy the model as we did in Section 11.5.
html heading: 'Edit'.
html form: [
html text: 'Title:'; break.
value: self model title;
callback: [ :value | self model title: value ].
html text: 'Due:'; break.
value: self model due;
callback: [ :value | self model due: value ].
callback: [ self answer: self model ];
callback: [ self answer: nil ];
text: 'Cancel' ]
Working directly on the model. Now the use of the cancel button does solve the problem in the above example, but generally this approach isn’t sufficient by itself: when a component returns an answer, you often want to do some additional validation on the potentially invalid object before updating your model.
Therefore, we should also modify the method
edit: to edit a copy of the item and, depending on the returned value of the editor, we should replace the current item with its modified copy.
| edited |
edited := self call: (ToDoItemView new model: anItem copy).
ifFalse: [ self model replace: anItem with: edited ]
Add the following method to
ToDoList>>replace: aTodoItem with: anotherItem
self items at: (self items indexOf: aTodoItem) put: anotherItem
Magritte Support. Replacing a copied object works well in our example, but does not if there are other references to the object (because you end up with a new object). One of the advanced features of Magritte (that we present in Chapter 26) is that it uses a Memento to support the automatic cancellation of edited objects: in other words, it copies the whole object during the edit operation into an internal data-structure and then edits only this object. As soon as the changes are saved, it walks over the Memento and pushes the changes to the real object.