Php 在atk4中,如何使用ajax更新视图
我目前定义了一个页面,它以行的形式显示一些数据。在每一行的末尾,都有一个视图,其中显示了从mysql中提取的总数Php 在atk4中,如何使用ajax更新视图,php,ajax,frameworks,agile,atk4,Php,Ajax,Frameworks,Agile,Atk4,我目前定义了一个页面,它以行的形式显示一些数据。在每一行的末尾,都有一个视图,其中显示了从mysql中提取的总数 $r->add('View_PointsLeft', 'pleft', 'pointsleft') ->setPoints($row['points_left']) ->setBacklog($row['backlog_ref']) ->setID($row['id'].'-points-lef
$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 -->
$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>
<?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');
}
}
我想在页面上发生更改时更新数据库,并更新总视图(以减少计数器)
首先,我想知道我是否采用了错误的方法(每个视图都应该是自包含的)-我是否应该将id字段传递给视图,将相关模型附加到lib/view/pointsleft.php中的视图,并使用模型值调用set字段
其次,如果我以这种方式进行更改,那么当使用ajax更改数据库值时,是否可以更轻松地使用特定id更新视图?如果是,我该如何做
第三,如果我还想根据客户端javascript上的一个操作触发对数据库的更新,我会把这段代码放在哪里?例如,在非atk4版本的代码中,我有一个名为using$.post(“update.php”)的脚本,它会更新mysql。我应该把这样的脚本放在ATK4的什么地方
提前谢谢
罗马人回答后更新 伙计,四块石头它比我预期的做得更多,我正忙于在视图中创建函数来填充每个字段名,所以现在使用addModel重做它 页面中的调用如下所示
<!-- 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 -->
$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>
<?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');
}
}
模板/视图如下所示
<!-- 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 -->
$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>
<?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');
}
}
我有一个if块,在页面中看起来像这样。我添加了Model_任务,并根据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();
}
然后在处理GET时在if块中调用它
$pleft=$this->pl_arr[$story];
$pleft->js()->reload()->execute();
但它失败了,出现了一个错误
AJAXec响应中的错误:语法错误:缺少;声明前
致命错误:在C:\wamp\www\paperless\page\scrumwall.php第247行的非对象上调用成员函数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();
}
用ATK4解决的问题:)您的结构似乎正常。如果对其使用setModel(),它将包含“pointsleft”和“backlog”字段,这些字段将自动填充 虽然我不知道setID是如何定义的,但是您可以扩展setModel,调用parent,然后执行它 我注意到的另一件事是,在模板中,最顶级的div应该具有id=''。这为视图提供了唯一的选择器,js()默认使用该选择器 您正在查找的.post函数是univ()->ajaxec()。它将数据发送到服务器,接收javascript并执行它,因此得名。它的行为与表单类似
$mybutton->js('click')->ajaxec($this->getDestinationURL(null,array('a'=>'b'));
if($_GET['a']){
// update database
$r->getElement('plfat')->js()->reload()->execute();
}
通常,为了使代码具有通用性,可以将上述代码放到视图中,但最好使用对象的名称,而不是“a”,如下所示。这样就不需要单独的页面处理更新:
$this->mybutton->js('click')->ajaxec($this->getDestinationURL(null,
array($this->name=>'reload'));
if($_GET[$this->name]){
// update database
$this->js()->reload()->execute();
}
更新 要澄清其执行顺序,请执行以下操作:
听起来好像有很多动作。实际上,每次点击2个请求,如果您立即重新加载,您可以消除一个请求。请注意,还可以将参数传递给reload(),然后从“get”获取该参数。我不完全理解是什么触发了您原始脚本中的操作,也许我们可以在?中找到这一点。好的,为了得到更清晰的答案,我收集了一个示例: 也许这里的例子更好地回答了这个问题 在您的情况下,因为您使用的是模型,所以应该更容易进行设置。对于性能,我决定使用两个列表器,但理论上也可以将每个人和任务作为一个视图
我在会话中存储关联(通过记忆),在您的情况下,您可以将它们存储在数据库中 好的,我现在有了一个模型,它根据原始问题的更新填充视图中的字段。我还将id移到了外部div(它位于内部div上,基于之前使用jquery直接更新左侧点的方式[没有ATK4的好处])。因此,我想在特定操作上执行视图的重新加载-不是单击按钮,但我假设主体将是相同的-我需要在视图中的哪个函数中放置js()->reload()->execute()的代码;我在星期四的其他地方怎么称呼它