Ein Widget kann auch mehreren Parametern im Browser bereitstellen. Dafür muss das Widget in der Methode GetProvidedParameterDefinitions mehrere WidgetParameterDefinition Objekte zurück liefern und im Browser mehrmals die Methode SetProvidedParameter aufrufen.

So kann ein Widget z.B. mit einem Parameter Benutzerprofile und mit einem weiteren Parameter Ordner bereitstellen. Das Widget könnte die Ordner eines Benutzers anzeigen und wählen lassen, damit ein anderes Widget den Inhalt der Ordner anzeigt. In diesem Beispiel wird das Widget die ersten 3 Ordner auflisten. In dem Fall werden DataWidgets in der Lage sein zu entscheiden, welchen Parameter sie nutzen.

TopUserProfilesWidget.cs

Das Widget liefert in diesem Fall zwei WidgetParameterDefinition zurück:

[Serializable]
public class TopUserProfilesWidget : Widget, IProvideWidgetParameter
{
	public TopUserProfilesWidget() : base()
	{
		Id = "669B0B80-6CFC-4388-AA09-FBAC5BC4D213".ToGuid();
		ToolboxName = "TopUserProfiles";
		Icon = "bank_building";
		ControllerName = nameof(TopUserProfilesWidget);
		PixelHeight = 300;
		HeightType = EnumWidgetHeightType.Pixel;
		CssClass = "top-user-profiles";
	}

	public override string GetTSClassName()
	{
		return "BA.Ui.Widgets.TopUserProfilesWidget";
	}

	public IReadOnlyList<WidgetParameterDefinition> GetProvidedParameterDefinitions()
	{
		return new List<WidgetParameterDefinition>() 
		{
			{ new OrmsWidgetParameterDefinition("42F7A053-91FC-44F3-9A6B-EA6E6B3B176D", "clickedUserProfile", EnumDataSource.UserProfileGuid, typeof(OrmsWidgetParameter)) },
			{ new OrmsWidgetParameterDefinition("26210EC1-320A-42CA-9CD5-7D1210365735", "clickedFolder", EnumDataSource.RecordCollectionGuid, typeof(OrmsWidgetParameter)) }

		};
	}
}

TopUserProfilesWidgetViewModel.cs

Das ViewModel beinhaltet in dem Fall zwei Listen von Tuple<string, OrmData>, mit den EntityTitles und die OrmData für beide Parametern im Browser.

public class TopUserProfilesWidgetViewModel
{
	public List<(string EntityTitle, OrmData ormData)> TopUserProfiles; 
	public List<(string EntityTitle, OrmData ormData)> TopFolders;

	public TopUserProfilesWidgetViewModel()
	{
		TopUserProfiles = new List<(string EntityTitle, OrmData ormData)>(); 
		TopFolders = new List<(string EntityTitle, OrmData ormData)>();
	}
}

TopUserProfilesWidgetController.cs

Der Controller liest die ersten 3 BenutzerProfile und die ersten 3 Ordner aus der DB und setzt diese in das ViewModel.

public class TopUserProfilesWidgetController : WidgetControllerBase
{
	public ActionResult Index()
	{
		TopUserProfilesWidgetViewModel viewModel = new TopUserProfilesWidgetViewModel();
		IQueryable<OrmUserProfile> query = API.Api.ORM.GetQuery<OrmUserProfile>();
		IQueryable<OrmRecordCollection> queryF = API.Api.ORM.GetQuery<OrmRecordCollection>();

		foreach (OrmUserProfile uProfile in query.OrderBy(ff => ff.LastName).Take(3))
		{
			OrmData uProfileData = new OrmData()
			{
				OrmTypeGuid = uProfile.OrmType,
				OrmGuid = uProfile.Oid,
				CacheId = uProfile.RecordCacheId,
				TemporaryKey = uProfile.TemporaryKey
			};

			viewModel.TopUserProfiles.Add((uProfile.EntityTitle, uProfileData));
		}

		foreach (OrmRecordCollection folder in queryF.OrderBy(ff => ff.Name).Take(3))
		{
			OrmData folderData = new OrmData()
			{
				OrmTypeGuid = folder.OrmType,
				OrmGuid = folder.Oid,
				CacheId = folder.RecordCacheId,
				TemporaryKey = folder.TemporaryKey
			};

			viewModel.TopFolders.Add((folder.Name, folderData));
		}

		return PartialView(viewModel);
	}
}

View: /Views/TopUserProfilesWidget/Index.cshtml

@model BA.Core.Models.TopUserProfilesWidgetViewModel

<div id="userProfiles">
	<ul>
		@foreach ((string entityTitle, BA.Core.Configuration.Pages.Parameters.OrmData ormData) in Model.TopUserProfiles)
		{
			string jsonOrmData = Newtonsoft.Json.JsonConvert.SerializeObject(ormData);
			<li data-ormdata="@jsonOrmData">@entityTitle</li>
		}
	</ul>
</div>
<div id="folders">
	<ul>
		@foreach ((string entityTitle, BA.Core.Configuration.Pages.Parameters.OrmData ormData) in Model.TopFolders)
		{
			string jsonOrmData = Newtonsoft.Json.JsonConvert.SerializeObject(ormData);
			<li data-ormdata="@jsonOrmData">@entityTitle</li>
		}
	</ul>
</div>

BA.Ui.Widgets.TopUserProfilesWidget.ts

Die TypeScript Klasse überschreibt die OnContentLoaded Funktion, um die Click Events auf die Einträge anzuhängen. Wenn ein Eintrag aus den Benutzerprofilen angeklickt wird, wird der Parameter vom TopUserProfilesWidget für die Benutzerprofile aktualisiert und nur die Widgets, die Benutzerprofile als Kontext selektiert haben, werden darauf reagieren. Genauso wird es passieren, wenn ein Eintrag aus Ordnern geklickt wird.

module BA.Ui.Widgets {
	"use strict";
	export class TopUserProfilesWidget extends Widget {
		public override OnContentLoaded(): void {
			let othis: TopUserProfilesWidget = this;

			$(this.GetWidgetJQIdSelector() + " #userProfiles ul li").click(function () {
				let parameter: BA.Ui.Widgets.Parameters.OrmsWidgetParameter = new BA.Ui.Widgets.Parameters.OrmsWidgetParameter();
				parameter.Orms.push($(this).data("ormdata"));
				othis.SetProvidedParameter<BA.Ui.Widgets.Parameters.OrmsWidgetParameter>("clickedUserProfile", parameter);
			});

			$(this.GetWidgetJQIdSelector() + " #folders ul li").click(function (){
				let parameter: BA.Ui.Widgets.Parameters.OrmsWidgetParameter = new BA.Ui.Widgets.Parameters.OrmsWidgetParameter();
				parameter.Orms.push($(this).data("ormdata"));
				othis.SetProvidedParameter<BA.Ui.Widgets.Parameters.OrmsWidgetParameter>("clickedFolder", parameter);
			});
		}
	}
}

Ergebnisse

DataWidgets können jetzt Auswählen, welchen Parameter sie nutzen. Als Beispiel wird die Seite zwei HelloWorldWidget beinhalten, jeweils nutzt ein Parameter vom TopUserProfilesWidget. Also, ein HelloWorldWidget wird auf Benutzerprofile reagieren und das Andere auf Ordner.


Beim Laden können die HelloWorldWidgets keinen Parameter lesen, weil nichts geklickt war:

Auf „Abraham Alder“ Klicken. Dann aktualisiert sich nur das linke HelloWorldWidget:

Auf „Ordner 3“ Klicken. Dann aktualisiert sich nur das rechte HelloWorldWidget: