【问题标题】:ajax widgets in pyramid and chameleon金字塔和变色龙中的 ajax 小部件
【发布时间】:2011-12-25 04:02:49
【问题描述】:

我希望能够在服务器端轻松创建由变色龙和金字塔支持的 ajax“小部件”。

Pyramid 是否提供任何可以简化编写小部件的管道代码?

我目前的方法是我有一个使用 home.pt 作为渲染器的主视图。 home.pt 使用宏 base.pt 定义页面结构并为 home.pt 提供一个插槽来填充。 base.pt 还使用了我编写的登录“小部件”宏(请参阅下面的 account_login_widget.pt)。

理论上,这一切听起来都很棒...我有一个可重复使用的登录小部件,可以在许多页面中使用,但我目前的方法效果不佳。我的登录小部件在其渲染器(服务器需要定义)中使用像 ${username} 这样的变量。我希望登录小部件及其呈现尽可能独立。但是以我目前的做事方式,主视图代码需要了解登录小部件的需求,并在字典中提供用户名、formrender 和其他变量。肯定不好……

我觉得我接近了正确的想法,但缺少一些东西......

有什么想法吗?

base.pt:

<html>
<head></head>
<body>
<div id="container">
    <div id="header">
        <span metal:use-macro="load: account_login_widget.pt"></span>     
    </div>
    <div id="middle">
        <span metal:define-slot="content"></span>
    </div>
    <div id="footer"></div>
</div>
</body>
</html>

home.pt:

<div metal:use-macro="load: base.pt">
<span metal:fill-slot="content">
    <div>my stuff</div>
</span>
</div>

account_login_widget.pt:

<span metal:define-macro="account_login_widget">
<script type="text/javascript">
(function($) {
    $.fn.my_function = function() {
        $('#login_form').submit(function(e) {
            e.preventDefault();

            // ajax call
            $.post(some_url, some_data, function(response) {
                $('#account_login_widget').html(response);
            });
        };
        return this;
    };
})(jQuery);

// Define the entry point    
$(document).ready(function() {
    $(document).my_function();
});
</script>

<div id="account_login_widget">
<div id="login_bar" tal:condition="not username">
    ${form_renderer.begin(...)}
        ... my form ...
    ${form_renderer.end()}
    <span tal:condition="login_failed">Login failed</span>
    <div id="forgot_password_link"><a href="#">Forgot Password?</a></div>
    <div id="create_account_link"><a href="${signup_url}">Create Account</a></div>
</div>
<div tal:condition="username">
    Welcome <strong>${username}</strong>! <a href="${logout_url}">Logout</a>
</div>
</div>
</span>

【问题讨论】:

  • 我应该提到我目前的想法是拥有一个 BaseView 类,我的所有视图都将扩展。在这个 BaseView 类中,我可以有一个 add Widget 方法,它将获取我的小部件视图对象并将其所有变量依赖项添加到我的视图最终将返回的字典中。

标签: python ajax pyramid chameleon template-tal


【解决方案1】:

处理此问题的一个好方法是将您的 account_login_widget 与其自己的视图相关联,例如:

@view_config(name='login_widget',
             renderer='templates/account_login_widget.pt')
def login_widget(request):
    return {'username': ...}

然后您应该能够访问 http://yourapp/login_widget 并仅取回小部件的 HTML。

剩下要做的就是调用视图并将生成的 HTML 包含在模板中。也就是说,而不是:

<span metal:use-macro="load: account_login_widget.pt"></span>

你会想要这样的东西:

<span tal:replace="structure render_view('login_widget')"></span>

render_view 但是在模板中不存在;你必须自己提供。最好使用渲染前事件:http://docs.pylonsproject.org/projects/pyramid/dev/narr/hooks.html#beforerender-event

from pyramid.events import subscriber
from pyramid.events import BeforeRender
from pyramid.view import render_view_to_response

@subscriber(BeforeRender)
def add_render_view_global(event):
    event['render_view'] = lambda name: render_view_to_response(context, request, name, secure).ubody

完成。如果您需要通过 AJAX 动态(重新)加载小部件,这种方法也将有所帮助。

【讨论】:

  • 谢谢!这个策略听起来不错,让我走得很远。尽管如此,仍然有一两个问题。您的建议是否假设使用遍历?我正在使用 url 调度。我遇到的问题是 '@view_config' 没有指定 route_name 所以找不到 url: yourapp/login_widget (这也意味着我的 ajax 帖子不起作用)。但是,当我指定除了名称之外的 route_name 时,对 render_view_to_response() 的调用不会解析为视图。看来我只能在“@view_config”中指定“name”或“route_name”,但不能同时指定。这里出了什么问题?
  • 添加两个 view_configs 似乎可以解决问题。组合谓词过于具体。但是添加 2 个 view_configs 似乎也很尴尬。 @view_config(name='account_login_widget', renderer='template/account_login_widget.pt') @view_config(route_name='account_login_widget', renderer='template/account_login_widget.pt')
  • 你是对的。我的答案 (@view_config) 的视图配置位假定遍历。如果您使用 url 调度,视图配置会有所不同。 docs.pylonsproject.org/projects/pyramid/dev/narr/…
猜你喜欢
  • 2011-08-27
  • 2023-03-03
  • 2013-07-14
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
相关资源
最近更新 更多