ISIS 1.16.2:无集合属性时@Action(invokeOn)转@Action(associateWith)方案咨询
invokeOn=OBJECT_AND_COLLECTION to associateWith for Query-Driven Collections in ISIS 1.16.2 Great question! Let's walk through how to migrate your deprecated invokeOn usage to ISIS's newer associateWith approach, even when your collection comes from a query action rather than a persistent entity field.
Background
The invokeOn=OBJECT_AND_COLLECTION flag was designed to make an action callable both from a single entity's detail view and from a collection view (with checkboxes for bulk operations). The replacement associateWith annotation is meant to link actions to specific collections—but since your collection is returned by a query (not stored as a field on an entity), we need to reference the query action itself instead.
Step-by-Step Solution
1. Assign an explicit ID to your collection query action
First, give the listAll action in your ConfigurationItems class a clear, explicit ID using the id parameter of the @Action annotation. This makes it easy to reference later:
public class ConfigurationItems { @Action( id = "listAll", // Explicit ID to reference in associateWith semantics = SemanticsOf.SAFE ) public List<ConfigurationItem> listAll() { return repositoryService.allInstances(ConfigurationItem.class); } // ... }
2. Update the delete action to use associateWith
Replace the deprecated invokeOn parameter with associateWith, pointing to the ID of your collection query action. This tells ISIS to make the delete action available both on individual entity views and on the collection view returned by listAll:
public class ConfigurationItem { @Action( associateWith = "listAll", // Links to the collection query action semantics = SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE, domainEvent = DeletedDomainEvent.class ) public Object delete() { repositoryService.remove(this); return null; } // ... }
3. Optional: Add a bulk delete method (for better UX)
While ISIS can automatically handle bulk operations using the single-entity delete method, adding an explicit bulk version makes your logic clearer and lets you return an updated collection to the user:
public class ConfigurationItem { // Existing single-entity delete method remains @Action( associateWith = "listAll", semantics = SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE, domainEvent = DeletedDomainEvent.class ) public Object delete() { repositoryService.remove(this); return null; } // Bulk delete method for collection view operations @Action( semantics = SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE, domainEvent = DeletedDomainEvent.class ) public List<ConfigurationItem> delete(List<ConfigurationItem> items) { items.forEach(repositoryService::remove); // Return the updated list after deletion return repositoryService.allInstances(ConfigurationItem.class); } // ... }
Key Notes
- If you have multiple query actions returning collections (e.g.,
listActiveItems,listArchivedItems), you can reference all of them inassociateWithusing a comma-separated list:associateWith = "listAll,listActiveItems". - Ensure the collection returned by your query action matches the entity type of the action (in this case,
ConfigurationItemor its subclasses) so ISIS can correctly link the action to the collection view.
内容的提问来源于stack exchange,提问作者JND

