我目前定义了一个页面,它按行显示一些数据。在每一行的末尾,有一个视图显示从 mysql 中提取的总数。
$r->add('View_PointsLeft', 'pleft', 'pointsleft')
->setPoints($row['points_left'])
->setBacklog($row['backlog_ref'])
->setID($row['id'].'-points-left');
视图是用这样的模板定义的
<!-- points left -->
<div class='target points_left'>
<div class='sticky green'>
<div class='story'><?$backlog?></div>
<div id='<?$name?>' class='big_points big_point_margin'><?$pointsleft?></div>
</div>
</div>
<!-- end 0000-points-left -->
使用循环页面中的 sql 选择填充视图的数据,并且 /lib/view/pointsleft.php 代码已设置方法,这些方法从页面传递参数并更新模板中的字段。
class View_PointsLeft extends View_Sticky {
function init(){
parent::init();
}
function setPoints($points){
$this->template->set('pointsleft',$points);
return $this;
}
function setBacklog($backlog){
$this->template->set('backlog',$backlog);
return $this;
}
function defaultTemplate(){
return array('view/scrumwall/pointsleft');
}
}
我想在页面上发生更改时更新数据库并更新总视图(以减少计数器)。
首先,我想知道我是否以错误的方式处理了这个问题(每个视图是否应该是自包含的) - 我是否应该将 id 字段传递给视图,将相关模型附加到 lib/view/pointsleft.php 中的视图并使用模型值调用设置字段?
其次,如果我以这种方式进行更改,那么当使用 ajax 更改数据库值时,是否可以更轻松地更新具有特定 ID 的视图,如果是这样,我该怎么做?
第三 - 如果我还想根据客户端 javascript 上的操作触发对数据库的更新,我会将这段代码放在哪里,例如在我的代码的非 atk4 版本中,我有一个名为 using $.post(" update.php"),它将更新 mysql。我会将这样的脚本放在 ATK4 的什么位置?
提前致谢。
罗马人回答后更新
伙计,ATK4 摇滚!- 它比我预期的要多,我正忙于在视图中创建函数来填充每个字段名称,所以现在使用 addModel 重做它,
来自页面的调用看起来像这样
$r->add('View_PointsLeft', 'pleft', 'pointsleft')
->loadData($row['id']);
模板/视图看起来像这样
<div id='<?$name?>' class='target points_left'>
<div class='sticky green'>
<div class='story'><?$backlog_ref?></div>
<div class='big_points big_point_margin'><?$points_left?></div>
</div>
</div>
lib/view 代码看起来像这样
<?php
class View_PointsLeft extends View_Sticky {
function loadData($id){
$this->setModel('Story')->loadData($id);
}
function init(){
parent::init();
}
function defaultTemplate(){
return array('view/scrumwall/pointsleft');
}
}
在罗马书的代码示例之后更新
在遵循 Romans 提供的代码示例之后,我现在使用 jquery 选择器在我的页面代码底部添加 URL 调用,并做一些 jiggery pokery 从 id 字段获取任务和状态(不确定使用 HTML5 only stufff using data- id 所以只需设置正常的 id 并从中提取)。以前放置代码在我自己的 univ.js 脚本中,但我无法从那里访问 php 变量,所以我将它移到页面中
$p->js(true)->_selector('.movable')->draggable();
$p->js(true)->_selector('.target')->droppable(array(
'drop'=>$this->js(null,'function(event,ui){'.
' target=$(this).attr("id").split("-");'.
' zone=target[2];'.
' sticky=$(ui.draggable).attr("id").split("-");'.
' task=sticky[1];'.
' switch (zone) {'.
' case "verify": newStatus="V";'.
' break;'.
' case "in": newStatus="P";'.
' break;'.
' case "to": newStatus="I";'.
' break;'.
' case "done": newStatus="D";'.
' break;'.
'}
$.univ().ajaxec({ 0:"'.$this->api->getDestinationURL().'",'.
'task: task, status: newStatus }); } ')
));
我有一个在页面中看起来像这样的 if 块。我添加 Model_Task 并根据 GET 参数加载值,因此我还可以获得更多信息,包括它相关的故事,因此如果状态现在完成,我也可以更新点。
if($_GET['task'] && $_GET['status'])
{
$new_status=$_GET['status'];
$task_id=$_GET['task'];
$t=$p->add('Model_Task')->loadData($task_id);
$old_status=$t->get('status');
$task_points=$t->get('points');
if ($new_status<>$old_status & ($new_status=='D' | $old_status=='D'))
{
$s=$p->add('Model_Story')->loadData($t->get('story_id'));
if ($old_status='D')
{
$s->set('points_left',$s->get('points_left')+$task_points);
} else {
$s->set('points_left',$s->get('points_left')-$task_points);
}
$s->update();
$story=$t->get('story_id');
}
$t->set('status',$new_status);
$t->update();
}
然后我可以计算新的点数并用剩下的点更新故事,并通过设置模型值和使用 update() 用 new_status 更新任务。
如果我现在移动其中一个可拖动对象,它可以工作,但会打开一个新窗口,再次显示整个页面并报告
AJAXec 响应中的错误:SyntaxError:语法错误
我认为打开额外的窗口是因为错误,但错误与具有整个页面的所有 html 的响应有关。除非状态是特定的,否则我实际上不希望从 ajax 调用中重新加载。
此外,我需要做的最后一件事是仅在页面上为已更新的特定故事重新加载一个视图。
我尝试过在第一次加载页面时创建一个数组并向其中添加短变量
$this->pl_arr[$row['id']]=$r->add('View_PointsLeft', 'pleft', 'pointsleft')
->loadData($row['id']);
然后在处理 GET 时在 if 块中调用它
$pleft=$this->pl_arr[$story];
$pleft->js()->reload()->execute();
但它失败并出现错误
AJAXec 响应中的错误:SyntaxError: missing ; before 语句致命错误:在第 247 行的 C:\wamp\www\paperless\page\scrumwall.php 中的非对象上调用成员函数 js()
最终更新
最后一个错误是因为我没有使用我想要更新的整个视图的外部 div 中的 id。一旦我改变了它,它就不再为空了。
所以第一次加载页面时,我将所有视图名称存储在一个循环中的关联数组中,因为我将它们放在页面上
$st = $p->add('Model_Story');
$result = $st->getRows();
foreach ($result as $row) {
if (is_array($row)) {
$r=$p->add('View_Scrumwall_StoryRow')
->setWorkspace('ws-'.$row['id']);
... other code here ...
$points_left[$row['id']]=$r->add('View_PointsLeft', null, 'pointsleft')
->loadData($row['id']);
}
然后有这样的 if GET 块
if($_GET['task'] && $_GET['status'])
{
$new_status=$_GET['status'];
$task_id=$_GET['task'];
$t=$p->add('Model_Task')->loadData($task_id);
$old_status=$t->get('status');
$task_points=$t->get('points');
if ($new_status<>$old_status && ($new_status=='D' || $old_status=='D'))
{
$s=$p->add('Model_Story')->loadData($t->get('story_id'));
if ($new_status=='D')
{
$s->set('points_left',$s->get('points_left')-$task_points);
} else {
$s->set('points_left',$s->get('points_left')+$task_points);
}
$s->update();
$story=$t->get('story_id');
//reload the points left sticky note for the story of the task
$js[]=$points_left[$story]->js()->reload();
}
$t->set('status',$new_status);
$t->update();
$js[]=$this->js()->reload();
$this->js(null,$js)->execute();
}
请注意,如果我只想更新页面上的一个视图,我可以通过重新加载调用该对象并执行例如
$pl->js()->reload()->执行
但是如果我想更新页面上的几个视图,我需要将它们放在一个数组中(这里称为 js[]),然后像这样调用执行 - 你也可以在 Roman 的 codepad 示例中看到一个示例。
$js[]=$points_left[$story]->js()->reload();
$js[]=$this->js()->reload();
$this->js(null,$js)->execute();
使用 ATK4 解决了问题 :)