【问题标题】:passing python data to javascript in web2py在 web2py 中将 python 数据传递给 javascript
【发布时间】:2016-11-08 10:39:44
【问题描述】:

这是我的问题。我有以下功能

def index():
    rows=db(db.mylist).select()
    return dict(rows=rows)

所以每当我重新加载前视图索引时,我都想从数据库中检索行并将数据以列表的形式显示给用户

{{for(r in rows)}}
    li.innerhtml={{=rows.task}}
{{pass}}

显然,这不是正确的做法。我想我必须使用 json 和 XML。

这是我正在使用的表

db.define_table(
   'mylist',
   Field('task', 'string')
)

<div class="col-sm-6">
         <div class="panel panel-default">
             <div class="panel-heading center " style="color: black; font-style: inherit">
                 <form>
                 Task:
                <input name="name" id="task"  />
                     <button type="button" class="btn btn-success btn-sm" onclick=add(),ajax('{{=URL('default','insert_task')}}',['name'])  >add</button>
                     </form>

             </div>

              <div class="panel-body center">
                  <ul id="list" class="list-group">  </ul>
              </div>

         </div>

     </div>
 </div>


var ul = document.getElementById("list");
var lastId=0;
function add()
    {
        if(!isBlank(document.getElementById("task").value)) {


            var iCon = document.createElement('div'); //create a div container
            var dbtMenu=document.createElement('div');
            var li = document.createElement("il");  //create a list-element
            var closeSpan = document.createElement("span"); //create a span for badge attribute
            var ClickListState=0;

            dbtMenu.setAttribute("class","container");
            //dbtMenu.appendChild(dropDownList);
            li.setAttribute('id',lastId); // set an attribute for id
            iCon.className = "glyphicon glyphicon-remove"; // image for remove button
            closeSpan.setAttribute("class", "badge"); //create a new attribute for span
            closeSpan.appendChild(iCon); // put it in the span set
            iCon.addEventListener("click",function(){var element=document.getElementById(li.getAttribute('id'));
                                                    element.parentNode.removeChild(element);}); //functionlity
            li.innerHTML = document.getElementById('task').value;
            var value=document.getElementById('task').value;
            var pass= document.getElementById('task').value;
            li.setAttribute("class", "list-group-item hover-yellow");
            li.addEventListener('click',function() {if(ClickListState==0){li.style.backgroundColor="red"; ClickListState++;}
                                                    else {li.style.backgroundColor="white"; ClickListState--; }});
            li.appendChild(closeSpan);
            lastId++;
            ul.appendChild(li);

        }
    }

function update()
    {
            {{for r in rows:}}
            var iCon = document.createElement('div'); //create a div container
            var dbtMenu = document.createElement('div');
            var li = document.createElement("il");  //create a list-element
            var closeSpan = document.createElement("span"); //create a span for badge attribute
            var ClickListState = 0;

            dbtMenu.setAttribute("class", "container");
            //dbtMenu.appendChild(dropDownList);
            li.setAttribute('id', lastId); // set an attribute for id
            iCon.className = "glyphicon glyphicon-remove"; // image for remove button
            closeSpan.setAttribute("class", "badge"); //create a new attribute for span
            closeSpan.appendChild(iCon); // put it in the span set
            iCon.addEventListener("click", function () {
                var element = document.getElementById(li.getAttribute('id'));
                element.parentNode.removeChild(element);
            });
           // var t ={#{=XML(response.json(r.task))}}
                    li.innerHTML = "t";
            var value = document.getElementById('task').value;
            var pass = document.getElementById('task').value;
            li.setAttribute("class", "list-group-item hover-yellow");
            li.addEventListener('click', function () {
                if (ClickListState == 0) {
                    li.style.backgroundColor = "red";
                    ClickListState++;
                }
                else {
                    li.style.backgroundColor = "white";
                    ClickListState--;
                }
            });
            li.appendChild(closeSpan);
            lastId++;
            ul.appendChild(li);

            {{pass}}

    }
    update();

【问题讨论】:

  • 我建议在继续使用您的应用程序之前阅读 web2p 文档。
  • 您好安东尼,感谢您的回复。我正在阅读文档并编写应用程序,但我只是没有很好的记忆力来保留所有信息。我可以保留 web2py 的工作流程,但我仍然在代码中伪造了一些技术方面。您在我之前的帖子中的回复非常有用。它解决了我的问题
  • 我仍然需要帮助。我们如何在 javascript 中使用行?
  • @Anthony 我实际上需要从表中获取元素“任务”并将其放入 li.innerhtml 中的 javascript –
  • 我认为您误解了模板的工作原理。所有 Python 代码(即在{{...}} 分隔符内)在页面被传递到浏览器之前在服务器上执行。因此,您的 Python 代码无法与 Javascript 代码交互(在 web2py 处理完整个页面后在浏览器中执行)。换句话说,你不能有一个 Python 循环在循环中运行一些 Javascript 代码。您需要更详细地解释您要达到的目标。

标签: javascript python json xml web2py


【解决方案1】:

阅读web2py中模板语言的基本语法here

你想要这个:

<ul>
    {{for row in rows:}}
        <li>{{=row}}</li>
    {{pass}}
</ul>

其他解决方案可以是,使用html helpers在控制器函数中构建完整列表并将其传递给查看

def index():
    rows = db(db.mylist).select()
    my_list = [row.task for row in rows]
    task_list = UL(*my_list)
    return dict(task_list=task_list)

而在视图中只是这样做:

{{=XML(task_list)}}

XML 是一个对象,用来封装不应该被 逃跑了。

我建议你看一下这两个例子:Image blogSimple wiki

编辑:

根据您的编辑,我认为您想使用表单添加新任务,并且想在不刷新页面的情况下添加列表。

阅读Ajax form submissionsimple wiki app中也给出了相关的ajax示例

<!-- Views/index.html-->
{{extend 'layout.html'}}

<form id="task_form">
     Task:
    <input name="name" id="task"  />
    <input type="submit" class="btn btn-success btn-sm" value="Add" />
</form>

<div id="target"> {{=XML(task_list)}}</div>


<script>
jQuery('#task_form').submit(function() {
  ajax('{{=URL("default", "insert_task")}}',
       ['name'], 'target');
  return false;
});
</script>

--

# Controller

def index():
    rows = db(db.mylist).select()
    my_list = [row.task for row in rows]
    task_list = UL(*my_list)
    return dict(task_list=task_list)

def insert_task():
    """an ajax callback that returns a <ul>"""
    task_name = request.vars.name
    db.mylist.insert(task=task_name)
    rows = db(db.mylist).select()
    my_list = [row.task for row in rows]
    task_list = UL(*my_list)
    return task_list

【讨论】:

  • 你会如何在 javascript 中做到这一点?
  • 我实际上需要从表格中获取元素“任务”并将其放在javascript中的li.innerhtml中
  • @TheMathNoob,您需要更详细地解释您要达到的目标。为什么需要通过 Javascript 设置 li.innerhtml 而不仅仅是通过 Python 创建 &lt;li&gt; 元素(假设您在浏览器中执行任何 Javascript 之前循环遍历服务器上的所有列表元素)?如果你真的需要通过 Javascript 处理一切,那么只需使用 web2py 将一些 Javascript 数据结构写入页面并使用 Javascript 处理所有处理。
  • @Gaurav Vichare 我将尝试再解释一次。 ADD() 函数将在本地显示数据。按下添加按钮后,ajax 函数会将数据存储在数据库中。如果我们重新加载网站,所有数据都会在视觉上消失,但会保留在数据库中。你知道重新加载整个页面相当于在控制器中调用索引,所以这个控制器将返回数据库中的所有行,这些行将传递给javascript中一个名为update的函数,该函数将数据直观地呈现给用户。 update() 将始终被调用
  • @TheMathNoob 再次更新了我的答案,所以现在索引控制器将返回所有任务并且视图将显示它,如果用户使用表单添加新任务,那么对 insert_task 函数的 ajax 调用将添加该值数据库,还将返回新的更新任务列表,该列表将插入目标 div。如果您刷新索引页面,那么无论如何都会返回所有任务并以列表格式显示。不需要 add() 和 update() js 函数。让我知道这是否解决了您的问题
【解决方案2】:

我想出这个来将一个 python 字符串列表转换为一个 javascript 字符串数组:

{{def print_js_array(left_side, pylist):

  wrap_quotes = map(lambda a: "'{}'".format(a), pylist)

  comma_separated = "" if not pylist else reduce(lambda a,b: "{}, {}".format(a,b), wrap_quotes)

  return "{} = [{}];".format(left_side, comma_separated)
}}

{{=SCRIPT(
  ""
  + print_js_array("var un_pythoned", status_filter_options))
}}

给定一个 python 列表['', 'Not Started', 'Running', 'Finished', 'Failed'] 导致 (html):

<script><!--
var un_pythoned = ['', 'Not Started', 'Running', 'Finished', 'Failed'];
//--></script>

使数组可用于后续脚本。您可能可以编写类似的东西来将字典打印为 json。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 2015-11-23
    • 2015-11-22
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多