Ajax 设计/重构在呈现新内容(如列表项和 div)时提供帮助
我在复制标记时总是遇到这种代码味道,而且我不太确定如何修复它。这是一个典型的用例场景:
假设我们想对某种文章发表评论。在文章下面,我们看到了一堆评论。这些是与原始页面请求一起添加的,并由模板引擎生成(在我的例子中是 Freemarker,但它可以是 PHP 或其他)。
现在,每当用户添加评论时,我们都希望创建一个新的 li 元素并将其注入当前页面的评论列表中。假设此 li 包含一堆内容,例如:
- 用户的头像
- 他们的名字
- 单击其个人资料或向他们发送私人消息的链接
- 他们写的文本
- 他们写评论的日期
- 一些“编辑”如果当前登录的用户有权执行这些操作,则“删除”链接/按钮。
现在,所有这些东西都已经写在我们最初生成页面的模板中......所以现在我们必须在 Javascript 中复制它!
当然,我们可以使用另一种模板语言 - 比如 Jquery 的模板插件 - 来减轻生成和附加这个新 li 块的痛苦...但我们最终仍然会得到稍微有点重复的 html 标记 不同是因为我们不能使用模板语言为我们提供的宏或其他便利。
那么我们如何重构重复的内容呢?这有可能吗,还是我们只能忍受?解决这个问题的最佳实践是什么?
I consistently come across this code smell where I am duplicating markup, and I'm not really sure how to fix it. Here's a typical use case scenario:
Let's say we'd like to post comments to some kind of article. Underneath the article, we see a bunch of comments. These are added with the original page request and are generated by the templating engine (Freemarker in my case, but it can be PHP or whatever).
Now, whenever a user adds a comment, we want to create a new li element and inject it in the current page's list of comments. Let's say this li contains a bunch of stuff like:
- The user's avatar
- Their name
- A link to click to their profile or send them a private message
- The text they wrote
- The date they wrote the comment
- Some "edit" and "delete" links/buttons if the currently logged in user has permission to do these actions.
Now, all of these things were already written in our template that originally generated the page... so now we have to duplicate it inside of Javascript!
Sure, we can use another templating language - like Jquery's Template plugin - to ease the pain generating and appending this new li block... but we still end up with duplicate html markup that is slightly different because we can't use macros or other conveniences provided to us by the templating language.
So how do we refactor out the duplication? Is it even possible, or do we just put up with it? What are the best practices being used to solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个常见问题,并且随着 UI 复杂性的增加而变得更加明显,并且必须在服务器和客户端模板上进行更改。通过在客户端和服务器端使用相同的模板标记可以解决此问题。模板处理器必须使用 JavaScript 和服务器端语言编写。
另外两个解决方案比上述方法更简洁,但都有各自的问题:
如果所有标记生成都在客户端完成,那么服务器的行为或多或少就像一个 Web 服务,它只以适合应用程序的任何格式发送回数据。 JSON 和 XML 是当今大多数 Web 服务非常流行的格式。客户端总是生成必要的 HTML 和 JS。如果采用这种方法,则必须明确定义客户端和服务器之间的边界。由于客户端对服务器上发生的情况了解有限,这意味着必须定义正确的错误代码。状态管理将变得更加困难,因为大多数/所有服务器交互将异步发生。使用此方法添加注释的示例可能如下所示:
另一种方法是在服务器端执行所有操作。每当发生更改时,都会向服务器发出请求,并要求其提供更新的视图。凭借快速的后端、不到一秒的响应时间以及适当的网络活动指示器,尽管服务器上发生了所有事情,应用程序都应该看起来非常敏感。上面的例子可以简化为:
虽然这在客户端看起来比以前的方法干净得多,但我们刚刚将标记生成移到了服务器。但是,如果应用程序不像 Google 地图那样非常 AJAXy,那么这种方法可能更容易使用。同样,这取决于应用程序的复杂程度,也许维护客户端状态对您来说是必要的,在这种情况下,您可能需要采用以前的方法。
This is a common problem and becomes more obvious as the UI complexity increases, and changes have to be done on both the server and client templates. This problem is fixable by using a the same template markup on both the client and server sides. The template processors must be written in both JavaScript and the server side language.
Two other solutions that are cleaner than the above approach, but both have their own problems:
If all markup generation is done on the client side, then the server acts more or less like a web service which only sends back data in whatever formats suits the application. JSON, and XML are really popular formats for most web services nowadays. The client always generates the necessary HTML and JS. If going with this approach, the boundary between the client and server must be well defined. Since the client has limited knowledge of what happens on the server, this means that proper error codes must be defined. State management will become harder since most/all server interaction will be happening asynchronously. An example of adding a comment with this approach may look like:
The other approach is to do everything server side. Whenever a change happens, shoot a request to the server, and ask it for the updated view. With a fast backend, response times under a second, and proper indicators of network activity, the application should seem very responsive despite everything happening on the server. The above example would be simplified to:
Although this seems a lot more cleaner on the client side than the previous approach, we have just moved the markup generation up to the server. However, if the application is not very AJAXy like Google Maps, then this approach may be easier to work with. Again, it's a matter of how complicated the application is, and perhaps maintaining state client side is a necessity for you, in which case you may want to go with the previous approach.