首页 \ 问答 \ 金字塔和变色龙中的ajax小部件(ajax widgets in pyramid and chameleon)

金字塔和变色龙中的ajax小部件(ajax widgets in pyramid and chameleon)

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

金字塔是否提供任何管道代码,使编写小部件变得容易?

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

从理论上讲,这听起来很棒......我有一个可重复使用的登录小工具,我可以在很多页面上使用,但是我目前的方法不能很好地工作。 我的登录窗口小部件在其渲染器(服务器需要定义)中使用像$ {username}这样的变量。 我希望登录小部件及其渲染尽可能独立。 但以我目前的做法,主视图代码需要知道登录窗口小部件的需求,并在字典中提供用户名,表单提交和其他变量。 绝对不好...

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

有什么想法吗?

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>

I would like to be able to easily create ajax 'widgets' backed by chameleon and pyramid on the server side.

Does Pyramid provide any plumbing code that would make writing widgets easy?

My current approach is I have a home view which uses home.pt as the renderer. home.pt uses a macro base.pt which defines the page structure and provides a slot for home.pt to fill. base.pt also uses a login 'widget' macro that I have written (see: account_login_widget.pt below).

In theory, this all sounds great...I have a reusable login widget that I can use in many pages, but my current approach doesn't work very well. My login widget uses variables like ${username} in its renderer (which the server needs to define). I want the login widget and its rendering to be as independent as possible. But with my current way of doing things, the home view code needs to be aware of the login widget's needs and provide username, formrender and other variables in the dictionary. Definitely not good...

I feel like I'm close to the right idea, but missing some things...

Any thoughts?

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>

原文:https://stackoverflow.com/questions/8063012
更新时间:2024-03-11 06:03

最满意答案

好。 问题在于计数器变量。 您不能在Apps脚本中使用全局变量。 有关更多信息,请参阅此答案 。 您可以使用ScriptProperties或CacheService作为替代方案。

var ss = SpreadsheetApp.getActiveSpreadsheet();
//Set up the Menu bar 
function onOpen() {
//  Logger.clear();
  var menuEntries = [ {name: "demo", functionName: "myFunction"}];
  ss.addMenu("Demo", menuEntries);
  // Store your counter in CacheService as a string.
  CacheService.getPrivateCache().put('counter','1',3600); 
}

function myFunction() {

  var myapp = UiApp.createApplication().setHeight(430).setWidth(800);;
  var button = myapp.createButton("Clicky");
  var myhandler = myapp.createServerHandler("secondfunction");
  var myhandler = button.addClickHandler(myhandler)
  myapp.add(button);
  ss.show(myapp);
}

function secondfunction()
{
   var cache = CacheService.getPrivateCache();
   var counter = parseInt(cache.get('counter'));
   counter ++; 
   cache.put('counter', counter.toString());
   Logger.log(counter);

}

OK. The problem is with the counter variable. You cannot use global variables that way in Apps Script. See this answer for more information. You can use ScriptProperties or CacheService as an alternative.

var ss = SpreadsheetApp.getActiveSpreadsheet();
//Set up the Menu bar 
function onOpen() {
//  Logger.clear();
  var menuEntries = [ {name: "demo", functionName: "myFunction"}];
  ss.addMenu("Demo", menuEntries);
  // Store your counter in CacheService as a string.
  CacheService.getPrivateCache().put('counter','1',3600); 
}

function myFunction() {

  var myapp = UiApp.createApplication().setHeight(430).setWidth(800);;
  var button = myapp.createButton("Clicky");
  var myhandler = myapp.createServerHandler("secondfunction");
  var myhandler = button.addClickHandler(myhandler)
  myapp.add(button);
  ss.show(myapp);
}

function secondfunction()
{
   var cache = CacheService.getPrivateCache();
   var counter = parseInt(cache.get('counter'));
   counter ++; 
   cache.put('counter', counter.toString());
   Logger.log(counter);

}

相关问答

更多
  • 使用Utilities.base64Encode HTTP Basic Authentication的正确标题如下所示: "headers": { "User-Agent": "MY_APP_NAME (App URL/your email address)", "Authorization": "Basic " + Utilities.base64Encode(username + ":" + password) }, The correct header for HTTP Basic ...
  • 我相信我知道这里的问题是什么。 Google Apps脚本上的“月份”触发器实际上是指每月[每月]每月 运行一次 。 您可以看到“每月”触发器为您提供最多31天的选择触发器,表示如果选择“15”,它将在每个月的15日触发。 我想这可能被误解为“每15个月运行一次”。 这里一个可能的解决方案是让它在每个月的31个月运行,因为它应该跳过几个月的数字,如果天数小于31的话。罗马日历的分割方式通常这意味着它将运行每个月两个月,有一些例外(7月和8月是背靠背,都有31天,12月和1月也是如此)。 I believe ...
  • 好。 问题在于计数器变量。 您不能在Apps脚本中使用全局变量。 有关更多信息,请参阅此答案 。 您可以使用ScriptProperties或CacheService作为替代方案。 var ss = SpreadsheetApp.getActiveSpreadsheet(); //Set up the Menu bar function onOpen() { // Logger.clear(); var menuEntries = [ {name: "demo", functionName: "my ...
  • 在Apps脚本提供的HTML中,您可以使用DOM对象,如Document对象和Document对象的getElementById()方法。 getElementById您也可以使用jQuery。 请参阅 - > 最佳实践 Apps Script使用JavaScript作为服务器端语言。 您不能在服务器端代码中使用DOM或jQuery。 使用新的html iframe模式,您可以在HTML(客户端)中使用angularJs。 HTML服务中存在JavaScript限制: https : //developer ...
  • 是的,可以每天写一个脚本来制作一份表格的副本。 简而言之,您将不得不复制导入的表格并将其粘贴到新工作表中。 每次打开/访问电子表格时,ImportHTML a都会更新。 所以只有存储表格的方法是将其复制并粘贴到新表格中。 这是代码,只是这样做: function getImportData() { var ss = SpreadsheetApp.getActive() var sheet =ss.getSheetByName("ImportSheet") if (sheet == null) { s ...
  • 事实上,它是可能的。 这得到Code.gs: function myFunction() { throw ScriptApp.getResource("Code").getDataAsString(); } It is, in fact, possible. This gets Code.gs: function myFunction() { throw ScriptApp.getResource("Code").getDataAsString(); }
  • 这是一个糟糕的答案,但我确实发现我能够简单地设置一个时间驱动的触发器,每分钟执行一次,这足以完成我的工作,尽管我可以想象你想要一个触发器的场景界面似乎有所承诺,但对我而言,它不适用于即将安排的事件。 This is a poor answer, but I did find that I was able to simply set a time-driven trigger with "every minute" execution, which was enough to finish my work, ...
  • 你最好的选择是使用第一种方法 sendEmail(recipient, subject, body, options) 此方法可以采用所有参数。 您在选项部分中传递了所有参数。 它看起来像这样。 // Send an email with two attachments: // a file from Google Drive (as a PDF) and an HTML file. var file = DriveApp.getFileById('12345mnopqrstuvwxyz'); var ...
  • “Google Apps脚本失败摘要”包含指向包含相关脚本的文件的链接。 仔细阅读。 The "Summary of failures for Google Apps Script" includes a link to the file holding the related script. Read it carefully.
  • 看起来你有一个JavaScript对象,你转换为JSON字符串, jstring 。 它只是一个字符串。 如果要访问字符串中表示的属性,请使用原始对象l 。 即, l.parameter.code function doPost(l) { var doc = DocumentApp.openById('1to3-JzhE27-LK0Zw7hEsdYgiSd7xQq7jjp13m6YwRh0'); var jstring = Utilities.jsonStringify(l); doc.appe ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)