简体   繁体   English

GWT活动和场所-如何理解这个概念?

[英]GWT Activities and Places - How to understand this concept?

Okay, Activities build on top of Places. 好的,活动建立在地方之上。 Places are " just URLs ". 地方就是“ 只是URL ”。 But I am just not getting it how to use them properly.. 但我只是不知道如何正确使用它们。

There are no nested Activities " because YAGNI "; 没有嵌套的活动“ 因为YAGNI ”; but how does it look like in this simple scenario: 但是在这种简单的情况下看起来如何:

  1. Having a login page 有一个登录页面
  2. Having an administration page that offers functionallity for 拥有一个管理页面,可为
    • Add events to my company 将事件添加到我的公司
    • Add items to my store 将商品添加到我的商店

After a successful login the "main container" of the website is cleared and filled with the new content of the admin-activity. 成功登录后,将清除网站的“主容器”并用admin-activity的新内容填充。 One thing that has to be changed here is the "display" of the ActivityMapper since now I got a navigation bar on the left side and a main-content Div on the right side. 这里必须更改的一件事是ActivityMapper的“显示”,因为现在我在左侧有一个导航栏,在右侧有一个主要内容的Div。

I could just have a LoginActivity and an AdminActivity . 我可能只有一个LoginActivity和一个AdminActivity That means I'd have urls like 这意味着我会有类似的网址

/#LoginPlace:noParams
/#AdminPlace:eventManager
/#AdminPlace:itemManager

But that's silly imho because for real I would like to have something like this: 但这真是愚蠢的恕我直言,因为实际上我想拥有这样的东西:

/#LoginPlace:noParams
/#AdminPlace:eventManager|storeId=1,langaugeId=2
/#AdminPlace:itemManager|storeId=1,langaugeId=2,page=0

But that would require my AdminActivity to break up the URL and look out for all this different types of URLs, right? 但这需要我的AdminActivity分解URL并查找所有这些不同类型的URL,对吗? What I mean is something like this: 我的意思是这样的:

private AdministrationActivity administrationActivity;

@Override
public Activity getActivity(Place place) {

    if (place instanceof LoginPlace) {
        return new LoginActivity((LoginPlace) place);
    } else if (place instanceof AdministrationPlace) {
        if(this.adminActivity== null) {
            this.adminActivity= new AdministrationActivity((AdministrationPlace) place);
        } else {
            this.adminActivity.updateMainContent(((AdministrationPlace) place).getUrl());
        }
        return this.adminActivity;
    }

    return null;
}

Where now adminActivity.updateMainContent() will have to do the parsing for all places in order to display the correct content. 现在adminActivity.updateMainContent()必须在所有位置进行解析才能显示正确的内容。

This would be the solution: 这将是解决方案:

/#LoginPlace:noParams
/#EventManagerPlace:storeId=1,langaugeId=2
/#ItemManagerPlace:storeId=1,langaugeId=2,page=0

But (!) now I need an activity for each place, right? 但是 (!)现在我需要在每个地方进行一次活动,对吗? And I am just not sure if there are equally as many places as there are activities. 我只是不确定是否有和活动一样多的地方。 I thought that one activity can navigate to different places. 我认为一项活动可以导航到不同的地方。

So how are Places and Activities supposed to used? 那么应该如何使用场所和活动?

The first questions you have to ask yourself is "where will the user possibly go?". 您必须问自己的第一个问题是“用户可能会去哪里?”。 As I understand it, you at a minimum have: 据我了解,您至少有:

  • list of events, with possible filter/selection criteria and paging attributes 事件列表,可能的过滤器/选择标准和页面调度属性
  • list of items, with possible filter/selection criteria and paging attributes 项目列表,以及可能的过滤器/选择标准和页面调度属性

Maybe you'll also have places like "details of an event" (maybe even split between read-only details and editable details, if the user will switch between both states; if the state depends on who the user is, then this is IMO the same place, and actions the user can do are different), "details of an item", "form to add an event", "form to add an item". 也许您还会有“事件的详细信息”之类的地方(如果用户将在两种状态之间切换,甚至可能在只读详细信息和可编辑的详细信息之间进行划分;如果状态取决于用户是谁,那么这就是IMO相同的位置,用户可以执行的操作也有所不同),“项目的详细信息”,“添加事件的表单”,“添加项目的表单”。

To me, login is a cross-cutting feature, it's not something the user comes to doing in your app (it's not a business use-case, not an "activity" that's part of the user's job). 对我来说,登录是一项跨领域的功能,这不是用户在您的应用程序中要做的事情(这不是业务用例,不是用户工作中的“活动”)。 You can still choose to use a place and activity for login though; 不过,您仍然可以选择使用地点和活动进行登录; so let's add that to the list: "login form" (definitely not how I'd do it, but that's another story). 因此,我们将其添加到列表中:“登录表单”(绝对不是我要怎么做,但这是另一个故事)。

Now you can choose how you want to represent those places as GWT Place objects: you can have one Place subclass with a property telling you which exact "place" you're on (basically what your AdminPlace:eventManager token suggests), or one Place subclass per "place" (what your EventManagerPlace token suggests). 现在,您可以选择将这些位置表示为GWT Place对象的方式:您可以拥有一个Place子类,该子类的一个属性告诉您所位于的确切“位置”(基本上是AdminPlace:eventManager令牌建议的内容),或者一个Place每个“地方”的子类( EventManagerPlace令牌建议的内容)。 This is entirely independent of whether you'll have one or several activities. 这完全取决于您将要进行一项还是多项活动。

The next question is about the various areas of the screen, that'll map to ActivityManager s: what parts of the screen do change when navigating? 下一个问题是关于屏幕的各个区域的信息,它们将映射到ActivityManager :在导航时屏幕的哪些部分会发生变化? Maybe they do not all change at the same time / under the same conditions. 也许它们并非同时/在相同条件下都发生变化。
So for example, should your navigation bar be within the activity or not? 因此,例如,您的导航栏是否应位于活动范围之内? If you can put it outside (because it's reused), do it. 如果您可以将它放在外面(因为它已被重用),请执行此操作。 It actually need not even be an activity if it's always the same (modulo the selected item). 如果它始终相同(对所选项目取模),则实际上甚至不必是活动。 In any case, it's probably a good idea to make it a singleton (or similar) and listening to PlaceChangeEvent s to select the appropriate item (not necessarily a "singleton", but at least not recreated on each navigation). 无论如何,将其设为单身(或类似PlaceChangeEvent )并听PlaceChangeEvent来选择适当的项(不一定是“单身”,但至少在每次导航时都不会重新创建)是一个好主意。 The advantage of putting the navigation bar outside the activities is that if you finally decide to have it vertical rather than horizontal (or the other way around), and/or collapsible, you won't have to change your activities (separation of concern). 将导航栏置于活动之外的优势在于,如果您最终决定将其垂直而不是水平(或相反)和/或可折叠,则无需更改活动(关注点分离) 。 If you ever have to build a mobile app, you could even have a "menu" place on that app that displays the navigation bar full-page and swaps it for the other activities when navigating. 如果您必须构建一个移动应用程序,甚至可以在该应用程序上放置一个“菜单”位置,以显示整个页面的导航栏,并在导航时将其交换为其他活动。

So we now have 2 display regions , ie 2 ActivityManager s, and their respective ActivityMapper s. 因此,我们现在有2个显示区域 ,即2个ActivityManager和它们各自的ActivityMapper Or maybe just one display region for the "main content", and the navigation bar is not an Activity. 或者,可能只是“主要内容”的一个显示区域 ,而导航栏不是活动。 The next step is to determine exactly what changes and when; 下一步是确定确切的更改以及更改的时间; ie when I go to place X, I need to have that thing in that area, and that other thing in that one; 也就是说,当我放置X时,我需要在那个区域中放那个东西,在那个区域中放另一个东西。 those "things" are your activities. 这些“事物”是您的活动。

The key to "model" your Activities is to think about the things the user does (activities) and focus on one of them. 对活动进行“建模”的关键是考虑用户所做的事情(活动)并专注于其中一项。 But Activities are also tied to how the user interacts with the application, and the navigation (eg when adding an item, does the form appears in a popup above the list, or replaces the list); 但是活动也与用户如何与应用程序交互以及导航相关联(例如,添加项目时,表单是否出现在列表上方的弹出窗口中或替换列表); so if you want to really completely separate concerns, you'd probably create some object to manage the list of events/items and have a really thin Activity that only instantiates and manages that object. 因此,如果您要真正完全分离关注点,则可能会创建一些对象来管理事件/项目列表,并拥有一个非常瘦的Activity,该实例仅实例化和管理该对象。 That's probably over-engineered as a starting point though, and it'll be relatively easy to factor the thing out of the Activity later if you feel it's needed. 不过,这可能是过度设计的起点,如果您觉得有必要,以后将其从Activity中排除相对容易。
I like (and that's basically how the feature has been designed) to have disposable activities. 我喜欢(基本上就是功能的设计方式)进行一次性活动。 In my ActivityMapper , everything from the Place that the Activity needs to know is passed to its constructor; 在我ActivityMapper ,一切从Place的活动需要知道被传递给它的构造; the Activity doesn't have to know the current place (or listen to place changes), and is not "mutated" by the ActivityMapper . Activity不必知道当前位置(或监听位置变化),并且不会被ActivityMapper “突变”。 There can of course be exceptions to the rule, for various reasons. 当然,由于各种原因,规则可能会有例外。 If you need to share state between "places" for a given activity (eg data caches, etc.), you don't necessarily have to reuse it, you can share the state via shared stateful objects and keep the activity mostly stateless. 如果您需要在给定活动的“场所”之间共享状态(例如,数据缓存等),则不必重复使用它,可以通过共享的有状态对象共享状态,并使活动大部分保持无状态。
Anyway, your idea of a big AdminActivity that itself swaps a big part of its content depending on the current place is akin to nesting. 无论如何,您想到一个庞大的AdminActivity本身会根据当前位置交换其大部分内容的想法类似于嵌套。

In the end, there's no one-size-fits-all, and you'll have to try and pick the strategy⋅ies that best fit your needs. 最终,没有一个万能的选择,您将不得不尝试选择最适合您需求的策略。

Last, but not least, don't design your place with a generic getUrl() that needs to be parsed ; 最后但并非最不重要的一点是,不要使用需要解析的通用getUrl()设计场所; parse everything in your PlaceTokenizer s; 解析PlaceTokenizer所有内容 nothing else than the tokenizers need to know how the place will look like in your URL (and you're not even forced to use a PlaceHistoryHandler to begin with, so your places might not even ever end up in the URL –your places won't be bookmarkable then and you won't be able to navigate in the app through the browser history) 除了令牌生成器之外,其他任何事情都不需要知道该位置在您的URL中的样子(而且您甚至没有被迫使用PlaceHistoryHandler开头,因此您的位置甚至可能永远都不会出现在URL中–您的位置将不会则无法添加书签,您将无法通过浏览器历史记录在应用中导航)
The key concept is separation of concerns. 关键概念是关注点分离。

I'd suggest you probably do want one Activity per Place. 我建议您可能确实希望每个地方进行一次活动。 There is generally a rough one to one relationship but they are split due to separation of concerns and so you can pass around a Place without an Activity. 通常存在一对一的粗略关系,但是由于关注点的分离,它们是分开的,因此您可以在没有活动的情况下绕过场所。

Adding parameters is sadly not supported by standard GWT. 遗憾的是,标准GWT不支持添加参数。 We created our own simple one based on UrlBuilder. 我们基于UrlBuilder创建了自己的简单代码。

There is a long standing issue for this https://code.google.com/p/google-web-toolkit/issues/detail?id=2422 (old issue tracker) which has other thoughts and links. 这个https://code.google.com/p/google-web-toolkit/issues/detail?id=2422 (旧问题跟踪器)有一个长期存在的问题,它还有其他想法和链接。

Once it is up and running it works really nicely. 一旦启动并运行,它就可以很好地工作。 I like using strongly typed objects and goTo rather than sticking URLs together. 我喜欢使用强类型对象和goTo,而不是将URL粘贴在一起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM