1

对于给定的报告,用户将希望有多个过滤选项。This isn't bad when the options are enumerations, and other 'static' data types, however things can get silly fast when you need a select list that is populated by fields stored in a table in the backend.

您如何处理这种情况?我发现自己不断地重塑视图数据以适应额外的过滤器字段,但它确实开始有点跟踪不仅选择的选项,而且还有选项本身......

没有更好的方法吗?

4

3 回答 3

2

I’m currently building out a new reporting section for one of our products at work and am dealing with this same issue. The solution I’ve come up with so far, though it hasn’t been implemented yet so this is still a work in progress, is along the lines of this.

There will be a class that will represent a report filter which will contain some basic info such as the label text and a list of option values.

public enum DisplayStyle
{
    DropDown,
    ListBox,
    RadioList,
    CheckList,
    TextBox
}

public class FilterOption
{
    public string Name { get; set; }
    public string Value { get; set; }
    public bool Selected { get; set; }
}

public class ReportFilter
{
    public string Title { get; set; }
    public DisplayStyle Style { get; set; }
    public List<FilterOption> Options { get; set; }
}

And then my model will contain a list of these option classes that will be generated based on each report’s needs. I also have a base report class that each report will inherit from so that way I can handle building out the option lists on a per report basis and use one view to handle them all.

public class ReportModel
{
    public string Name { get; set; }
    public List<ReportFilter> Filters { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

Then inside my view(s) I’ll have some helper methods that will take in those option classes and build out the actual controls for me.

public static string ReportFilter(this HtmlHelper htmlHelper, DisplayStyle displayStyle, FilterOption filterOption)
{
    switch (displayStyle)
    {
        case DisplayStyle.TextBox:
            return string.Format("<input type=\"text\"{0}>", filterOption.Selected ? (" value=\"" + filterOption.Value + "\"") : string.Empty);
            break;
        ...
    }
}

My route would look like this

Reports/{reportID}/start/{startDate}/end/{endDate}/{*pathInfo}

All reports have a start and end date and then optional filters. The catchall parameter will have lists of filter values in the form of “Customer/1,4,7/Program/45,783”. So it’ll be like a key/value pair in list form. Then when the controller loads it’ll parse out those values into something more meaningful.

public static Dictionary<string, string> RouteParams(string pathInfo)
{
    if (string.IsNullOrEmpty(pathInfo))
    {
        return new Dictionary<string, string>();
    }

    var values = new Dictionary<string, string>();

    // split out params and add to the dictionary object

    return values;
}

Then it will pass them off to the report class and validate them to make sure they’re correct for that report. Then when the options are loaded for that report anything that’s been set in the URL will be set to Selected in the ReportOption class so their state can be maintained. Then the filter list and other report data will be added to the model.

For my setup some filters will change when another filters selection changes so there will be some AJAX in here to post the data and get the updated filter options. The drilldown will work sort of like the search options at amazon or newegg when you narrow your search criteria.

I hope that all makes sense to someone beside me. And if anyone has some input on improving it I’d be happy to hear it.

于 2009-02-05T06:06:58.327 回答
1

您可以使用 MVC 应用程序中的 jQuery 和 JsonResults 在屏幕上异步检索数据,这就是我们在应用程序中填充所有列表和搜索的方式。 我有一个如何在这里完成的例子。

这样视图数据是按需加载的,如果他们不使用额外的过滤器,那么他们就不必获取视图数据,如果一个选择与另一个相关,那么很清楚您需要检索哪组数据。

另一种选择,虽然我不太喜欢这个,但 jQuery 解决方案可能不适合你,是让你的视图模型对象包含所有视图数据,这样你需要做的就是设置单个模型对象和所有列表是直接加载的并且是强类型的。这将简化视图和后端代码,因为更清楚的是,对于此视图,您唯一需要的是此模型对象的完整版本。

例如,如果您有两个组合框列表,那么您的模型可能如下所示:

public class MyViewMode
{
    public int MyProperty { get; set; }
    public string SomeString { get; set; }
    List<string> ComboListA { get; set; }
    List<string> ComboListB { get; set; }
}

希望这是有道理的,如果没有,请发表评论,我将对此进行扩展。

于 2009-01-12T22:46:06.553 回答
0

Ad-hoc filtering on reports is indeed a tricky issue especially when you want to show a custom user interface control based on the data type, do validation, make some filters to be dependent on one another and others not, etc.

One thing I think that is worth considering is the old "build vs buy" issue here. There are specialized tools out there for ad-hoc reporting that do provide a UI for ad-hoc filters help with this such as the usual suspects Crystal Reports, Microsoft's Reporting Services, or our product ActiveReports Server. In ActiveReports Server we support cascading prompts (where available values in prompts depend on one another) and make it easy for anyone, even non-technical business users to modify the prompts (assuming they have permissions obviously). More information about using prompts in ActiveReports Server is here. ActiveReports Server 也是所有托管的 .NET 代码,并提供 ASP.NET 控件和 Web 服务,允许您将其集成到您的 Web 应用程序中。

Scott Willeke
Product Manager - ActiveReports Server
GrapeCity inc.
于 2012-07-16T20:01:09.627 回答