Damit eine Aktion alle selektieren Datensätze auf dem Server verarbeiten kann, wird ein Igniter benötigt. Man kann steuern, ob alle Datensätze verarbeitet werden sollen, wenn nichts selektiert ist (AllRecordsIfNothingIsSelectedIndicator), ob die Oids der Datensätze in eine Tabelle abgelegt werden (CreateTemporaryRecordsIndicator) und ob die Oids nur einmal in der Liste vorkommen dürfen (UniqueRecordListIndicator).

public class MyFirstIgniter : OperationOverSelectedRecordsIgniterBase
{
    public MyFirstIgniter(IgnitionModel ignitionModel) : base(ignitionModel)
    {
        AllRecordsIfNothingIsSelectedIndicator = false;
        CreateTemporaryRecordsIndicator = false;
        UniqueRecordListIndicator = true;
    }
}

In der Methode Ignite() werden die selektierten Datensätze verarbeitet.

public override ActionResult Ignite()
{
    if (SomethingSelected)
        foreach (RelationData record in Records)
        { }
    return null;
}

Wenn man CreateTemporaryRecordsIndicator = true; gesetzt hat wurden die Oids in einer Tabelle abgelegt. In TaskExecutionId steht eine Id über die man die Oids wieder auslesen kann. Anschließend muss man die Sätze in der temporäre Tabelle löschen.

public override ActionResult Ignite()
{
    if (SomethingSelected)
    {
        Session session = Api.ORM.GetNewSession();
        IQueryable<OrmTempSelectedRecords> query = Api.ORM.GetQuery<OrmTempSelectedRecords>(session);
        query = query.Where(ff => ff.TaskExecutionId == TaskExecutionId);
        // Laden der Guids
        IQueryable<Guid> guids = query.Select(ff => ff.SelectedRecordOid);
        // Laden der Rlationsdaten
        IQueryable<RelationData> relationData = query.Select(ff => new RelationData() { Oid = ff.SelectedRecordOid, OrmType = ff.SelectedRecordType });
        // Laden von beliebigen Datensätze
        IQueryable<OrmBABase> orms = Api.ORM.GetQuery<OrmBABase>(session).Where(ff => query.Select(q => q.SelectedRecordOid).Contains(ff.Oid));
        // Laden von konkreten Datensätze
        IQueryable<OrmMyDataTable> myDataTable = Api.ORM.GetQuery<OrmMyDataTable>(session).Where(ff => query.Select(q => q.SelectedRecordOid).Contains(ff.Oid));
        // Verarbeitung
        ....
        // Löschen der temporären Sätze
        foreach (OrmTempSelectedRecords record in query)
        {
            record.Delete();
        }
    }
    return null;
}

Über IgnitionModel.Parameters kann man Parameter auslesen, die von der UI gesetzt wurden.

public override ActionResult Ignite()
{
    if (IgnitionModel.Parameters.TryGetValue("Start", out object startObj) && startObj is bool start && start)
    { }
    return null;
}

Es wird ein ActionResult zurückgegeben. Dies kann null sein oder JsonResult mit JsonFormResult als Objekt. In dem Beispiel wird die aktuelle Ansicht aktualisiert.

return new JsonResult() { Data = new JsonFormResult() { RefreshGrid = true } };

Die Aktion implementiert nicht ClientActionBase sondern ClientActionGridMassOperationBase. Sinnvolle Einstellungen für die Sichtbarkeit der Aktion sind.

DynamicClientVisibility.Add(EnumActionVisibility.ManySelected);
DynamicClientVisibility.Add(EnumActionVisibility.NothingSelected);
DynamicClientVisibility.Add(EnumActionVisibility.OneOrNothingSelected);
DynamicClientVisibility.Add(EnumActionVisibility.OneSelected);

Massenoperationen laufen auf alle Datensätze, wenn nichts selektiert ist. Wenn dies nicht der Fall sein sollte, muss dies gesetzt werden

SomethingMustBeSelected = true;

Der Anwender kann über den Start der Massenoperation per Toaster-Meldung informiert werden

OperationStartedMessage = "Meine Massenoperation startet";

Als nächstes muss der Igniter gesetzt werden. Es muss darauf geachtet werden, das der AssemblyQualifiedName gesetzt wird.

MassOperationIgniter = typeof(MyFirstIgniter).AssemblyQualifiedName;

Die Massenoperation wird in Type Script ausgelöst. In einer Type Script Aktion, sind alle notwendigen Informationen zum Starten des Igniters in den customData vorhanden. Es müssen lediglich notwendige Parameter des Igniters selbst gesetzt werden.

public static ClientActionAddService(event: any, customData: CustomData) {
    let igniterParams: CustomData = {};
    igniterParams['myParameter'] = true;
    customData["MassOperationIgniterParameters"] = JSON.stringify(igniterParams);
    BA.Ui.Actions.GridActions.StartMassOperation(event, customData);
}

Möchte man einen Igniter außerhalb einer Aktion starten, so tut man dies in dem man die Informationen selbst setzt.

let igniterParams: CustomData = {};
igniterParams['myParameter'] = false;
customData["MassOperationIgniter"] = "BA.Training.Igniters.MyFirstIgniter, BA.Training";
customData["MassOperationIgniterParameters"] = JSON.stringify(igniterParams);
BA.Ui.Actions.GridActions.StartMassOperation(null, customData);