金字塔和变色龙中的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
最满意答案
好。 问题在于计数器变量。 您不能在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 ...
-
每2个月运行一次的Google Apps脚本触发器无效(Google Apps Script trigger to run every 2 months is not working)[2022-04-07]
我相信我知道这里的问题是什么。 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.
-
Google Apps脚本中的JSON(JSON in Google Apps Script)[2023-08-14]
看起来你有一个JavaScript对象,你转换为JSON字符串, jstring 。 它只是一个字符串。 如果要访问字符串中表示的属性,请使用原始对象l 。 即, l.parameter.code function doPost(l) { var doc = DocumentApp.openById('1to3-JzhE27-LK0Zw7hEsdYgiSd7xQq7jjp13m6YwRh0'); var jstring = Utilities.jsonStringify(l); doc.appe ...