jqgrid + MVC: How to open a dialog inside jqgrid? Which methods do you suggest to open a dialog?
我正在将MVC 4 EF 4.1与jqgrid一起使用。
我是HTML新手
- 您能否更清楚地描述所执行步骤的逻辑。例如1)您用一些数据填充网格。行为栏是否包含您在注释中显示的?您真的需要在网格的每一行中都具有所有data-dialog-...属性吗?不同行中的值不同?您如何填写行为专栏?您是否使用自定义格式化程序?我不理解在上创建live绑定的意义。在$(".openDialog").live("click"处理程序中使用所需的参数定义函数并直接调用该函数是否更容易?
-
THX再次奥列格。抱歉,我错了。我没有使用自定义格式化程序,我以前使用过它们,现在我在gridcomplete中使用该代码。关于属性,我需要它们,因为我在整个解决方案中使用了相同的opendialog函数,因此属性在调用它的例程的函数中可能会有所不同。腓骨我做错了事...请澄清一下:为什么您告诉我我正在对进行实时绑定?对我来说,绑定已在$(".openDialog").live("click")上,如第一段代码中所述...我正在回答您的其他评论。谢谢!
-
我刚刚发布了答案的"更新"部分。关于"实时"的问题:它有很多限制,并且总是像bind一样缓慢,但是它允许您实现对页面上尚不存在的元素的"绑定"。我在上一条评论中的意思主要是首先将一些参数放置到元素的data-属性中,然后从事件句柄中获取它。取而代之的是,您可以定义onclick属性,该属性使用任何参数调用某些函数。例如onclick="myFunc(580,740, mycontrolllertestDlgBlaBla);return false;"。
我不确定我是否理解您的要求。我建议您使用答案中描述的jQuery.jqGrid.dynamicLink.js,您可以从此处下载,也可以从此处下载最新版本(并在此处下载)。 formatter: 'dynamicLink'的用法非常简单,您几乎可以在jqGrid内部实现每个链接。您可以使用onClick回调来创建所需的对话框。
对您的代码再说一遍。每次单击时,创建代表对话框的并将其放置在页面的<body>中。 close事件仅隐藏div,而不会将其从主体中删除。因此,第一个问题是:您的页面每次点击将越来越长。第二个问题是可能会获得HTML不允许的id重复项,如果您添加具有相同id的不同元素,则会产生很多非常奇怪的效果。因此,在当前代码中使用data-dialog-id属性时应格外小心。
已更新:我想评论您发布的gridComplete中的代码。它不是有效的,您可以使用自定义格式化程序来获取更清晰有效的代码。您没有发布使用的jqGrid的完整代码,但我想您在colModel中至少有两列:'act'和'myrow'。您不能将具有href的元素放置在'act'列中,这些元素是基于'myrow'列中的值构造的。
当前代码的作用。 1)将构建网格并将其放置在页面上,该页面的" act"列为空。然后在gridComplete内部执行以下操作:a)调用getDataIDs,它将遍历整个网格并从数组ids中的每一行收集ID。 b)调用getRowData,它将遍历整个网格,并从对象的所有列中收集所有数据,并将对象放置在数组rows中。 c)获取" myrow"列的内容,构造并将其放置在网格的每一行的'act'列*中。您还应该了解,在Web浏览器上更改页面上的一个元素之后,必须重新计算页面上每个元素的位置。
因此,要提高页面的性能,您首先应该减少页面上元素的修改。重写代码并获得相同结果的最有效方法是使用自定义格式化程序。在这种情况下,您可以仅在colModel中的'act'中包含附加属性:
1 2 3 4 5
| { name: 'act', index: 'act', width: 75, sortable: false, search: false,
formatter: function (cellvalue, options, rowObject) {
return '<a class="mybuttonclass openDialog" data-dialog-id="tckDetDlg" data-dialog-autosize="false" data-dialog-alt="580" data-dialog-larg="740" data-dialog-title="test dialog" href="/mycontrolller/testDlg/' +
rowObject.myrow + '">';
}} |
您还应该验证是否使用jqGrid的gridview: true选项。修改后的代码将执行以下操作。在构造网格主体的HTML片段期间,完整的HTML片段将被构建为一个字符串,并将通过一次操作将其放置到HTML页面中。目前,Web浏览器将重新计算页面上其他元素的位置,所有操作都将完成。因此,代码将是相同的,它将变得更短,更易于阅读,并且将更加有效,特别是在网格的行数很多的情况下。
如果要使用我在代码之前建议您使用的dynamicLink格式化程序,则可以如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| { name: 'act', index: 'act', width: 75, sortable: false, search: false,
formatter: 'dynamicLink', formatoptions: {
onClick: function (rowid, iRow, iCol, cellValue, e) {
var myrow = $(this).jqGrid('getCell', rowid, 'myrow');
$("", {id:"tckDetDlg"})
.addClass("dialog")
.appendTo("body")
.dialog({
height: 580,
width: 740,
autoResize: false,
position: 'top',
title: 'test dialog',
close: function () { $(this).remove() },
modal: true,
buttons: {"Ok": function () { $(this).dialog("close"); } }
})
.load('/mycontrolller/testDlg/' + myrow);
}
}} |
我认为上面的代码很容易阅读和理解。 onClick中的代码将与您可以在ondblClickRow内部使用的代码相同。在这两种情况下,您只需要知道rowid。因此,您可以将onClick的代码放在函数中,而不是使用匿名函数,然后在两种情况下都调用该函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| // first define the callback function which we will use later
var myClickHandle = function (rowid) {
var myrow = $(this).jqGrid('getCell', rowid, 'myrow');
$("", {id:"tckDetDlg"})
.addClass("dialog")
.appendTo("body")
.dialog({
height: 580,
width: 740,
autoResize: false,
position: 'top',
title: 'test dialog',
close: function () { $(this).remove() },
modal: true,
buttons: {"Ok": function () { $(this).dialog("close"); } }
})
.load('/mycontrolller/testDlg/' + myrow);
};
...
// define the grid
$("#jqTicketgrid").jqGrid({
...
colModel: [
...
{ name: 'act', index: 'act', width: 75, sortable: false, search: false,
formatter: 'dynamicLink', formatoptions: { onClick: myClickHandle } }
...
],
ondblClickRow: function (rowid) {
myClickHandle.call(this, rowid);
} |
- 非常感谢奥列格!我按照我提出的另一个问题的建议解决了问题。基本上,现在我使用的是自定义格式化程序,在其中为所需的每个按钮/操作放置一个按钮样式的锚点。关于您的评论,请您告诉我如何删除动态添加的代码?此外,您是否也可以看一下与此类问题有些相关的这个问题?非常感谢你!
-
@拉里:不客气!您可以使用jQuery.remove从页面中删除和现有元素。所有孩子也将被删除。例如,您可以使用$(#tckDetDlg).remove()删除id =" tckDetDlg"的旧对话框。如果页面上不存在带有id的元素,则该代码不执行任何操作。因此,您可以在$("")...之前包括行$(# + $(this).attr("data-dialog-id")).remove();。答案有效,但似乎我不好。为什么不只将window.location分配给新URL?
-
@Larry:因为您是写的,所以您是JavaScript的新手,我在答案的后面加上" UPDATED"部分,其中描述了如何重写代码以使其从性能angular更可读和更有效。
-
THX为您提供了宝贵的帮助,我将按照您的建议放置$.remove代码。关于window.location,请您告诉我为什么您认为它不好吗?考虑到我只想打开一个对话框,而分配window.location不会造成一些我无法想象的问题,而主要的window.location始终是相同的,直到用户不导航解决方案?谢谢
-
@Larry:稍后,您似乎已经在对话框的close句柄内使用了$(this).remove();。如果要转到某些URL,window.location的用法非常简单。您只需将URL分配给window.location:window.location = mycontrolllertestDlg123;。我认为在问题描述的情况下,您不需要这样做,因为仅将使用的URL用作jQuery.load的参数。
-
哇!非常感谢Oleg!您总是如此准确,将问题排在中心!它是完美的,已经教会了我很多东西,使我理解了各种各样的错误。请澄清一下(其余的我会严格遵循您的宝贵建议):关于act列,为简单起见,我没有指定我必须为每一行放置多个按钮。在这种情况下,我将能够使用onclick事件,还是将所有内容保留在自定义格式化程序中?例如,要使用点击处理程序,我可以为每个动作创建一列,但将它们全部显示在一个动作中吗?谢谢!
-
@拉里:"是的,你可以的"将是我认为所有问题的答案。如果发布更多您使用的完整代码会更好。至少有两列像行为。如果需要,可以在一个单元格(列)中放置许多链接。您也可以使用<button>代替,并且在一列内有许多按钮。您只需要更详细地描述原始问题,并确保可以用简单明了的方式解决它。