0

好的,让我们开始吧。

此代码在控制台中运行良好,可以执行所需的操作。

$('#tasks-table input').parent().html($('#tasks-table input').siblings('textarea').val())

但在这样的调用中,它甚至不会执行。控制台是沉默的。所有其他功能代码都正确执行

updateTask.call(this, 131)

有任何想法吗?

更新

$('#tasks-table input').parent().html($('#tasks-table input').siblings('textarea').val())

是其中的一部分

updateTask.call(this, 131)

并在 updateTask 中被忽略,这条指令在控制台上工作得很好,但当它是 updateTask 的一部分时不会

html 是一个 4 行 php 生成的表,其中有一行典型的

<tr>
  <td><?php echo $task->id ?></td>
  <td onclick='projects.editTask.call(this, <?php echo $task->id ?>)'><?php echo $task->text ?> </td>
  <td><?php echo $task->status ?></td>
  <td><?php echo $task->controls ?></td>
</tr>

editTask 是一个简单的替换功能(td 的内容变成了 textarea)

if(block || !($(this).attr('incomplete'))) return; //only one is allowed
block = true;
if(!$(this).children('textarea').length) {
   $(this).html('<textarea style="width: 100%; height: 110px;">'+$(this).html()+'</textarea><br/><input type="button" value="Сохранить" onclick="projects.updateTask.call(this, '+parseInt(id)+')" />');
} 

updateTask 的目标是将 td 中的任何内容替换回 textarea 的内容,并使用 updateTask 的 $.post 内容将更新请求发送回服务器

var text = $(this).siblings('textarea').val();
//does not work only here, but works anywhere else
$('#tasks-table input').parent().text($('#tasks-table input').siblings('textarea').val())
$.post('/projects/ajax/', {
   ajax: true,
   command: 'update',
   id: id,
   text: text }
  , function() { 
     block = false; 
  }); 

当我以更复杂的方式进行操作时,它会起作用。像这样更简单的方法:

$(this).parent().html(text)

也没有用

4

1 回答 1

0

编辑: 重新审视你的问题,看起来我关注的重点可能不是问题所在。我不会删除它,因为它是您发布的代码的有效问题。未查询或修改 textarea 值的问题很可能是因为您在textareaDOM 加载后添加了 。您应该能够在您的表上使用jquery.live()事件或在本文末尾使用委托事件。两者都适用于任何当前或未来的 DOM 元素。在执行任何 DOM 操作或基于 ajax 的 HTML 更新时,这些都是救命稻草。这也可以解释为什么您能够在控制台而不是代码中执行操作。

原始答案: 我不确定这是否会完全有帮助,但我认为阻止您的代码执行的是:

if(block || !($(this).attr('incomplete'))) return;

当您的表格单元格没有该属性时,您实际上是在执行:

if( block || !(undefined) ) return;

这将永远是真的,因为!(undefined)它是真的。您很可能希望强制使用布尔值:

if( block || !!(undefined) ) return;

如果您只期望undefined和任何文本值,这很好。修改此条件的更好方法是明确检查您期望的值(我假设您期望为“真”):

if(block || ($(this).attr('incomplete') === "true") ) return;

建议:

我会提出的一个建议是,不要内联 onclick 函数,而是使用 HTML5 data-* 属性来存储您的数据并在一个地方执行代码。这有助于将 JavaScript 保存在一个地方,并且不会在整个 HTML 中混合使用它。

例如,您可以data-id为每个表格单元格生成一个属性,并将表格行标记为可编辑data-edit-cell="true"

<table>
<tr data-edit-cell="true">
  <td data-id="1">cell one</td>
  <td data-id="2">cell two</td>
  <td data-id="3">cell three</td>
  <td data-id="4">cell four</td>
</tr>
</table>​

然后,第二个建议,而不是将单击事件绑定到每个单元格,您可以使用jquery.delegate()将事件绑定到行 ,它监视由选择器 ( td ) 定义的子项的冒泡事件 ( click ):

var block = false;
$('tr[data-edit-cell=true]').delegate('td', 'click', function() {
    if (block || $(this).attr('incomplete') === "true" ) return; //only one is allowed
    block = true;
    console.log('clicked: ' + $(this).attr('data-id'));
});​

我在这里创建了一个 jsfiddle,因此您可以查看此代码。

于 2012-08-08T13:01:13.297 回答