jQuery 内的 Volt 模板引擎
Volt Template Engine inside of jQuery
我有一个(也许)非常独特的问题。您可以查看下图以便更好地理解。
select 区域中的设备在控制器中获取,然后我用 Volt 循环遍历它们并在 <option>
标签中回显它们,如下面的代码所示:
<select class="form-control">
<option value="0">No equipment</option>
{% for item in equipment %}
<option value="{{ item.id }}">{{ item.name }}</option>
{% endfor %}
</select>
用户可以按加号按钮添加另一个设备。整个 <tr>
被克隆并通过 jQuery 附加。问题是,当我想遍历设备时。伏特代码未被解析,而是被 jQuery 显式回显,如下图所示。
克隆代码是这样的(我想这很老套,不过我不知道有更好的替代方法):
$('#addEquipment').bind('click', function() {
var $div = $('tr[id^="rowEquipment"]:last');
var num = parseInt($div.prop('id').match(/\d+/g), 10) + 1;
var $clone = $div.clone().prop('id', 'rowEquipment' + num);
var $equipment = '<td>'+
'<div class="row">'+
'<div class="col-sm-1">'+
'<p class="form-control-static">Equipment:</p>'+
'</div>'+
'<div class="col-sm-3">'+
'<select class="form-control">'+
'<option value="0">No equipment</option>'+
'{% for item in equipment %}'+
'<option value="{{ item.id }}">{{ item.name }}</option>'+
'{% endfor %}'+
'</select>'+
'</div>'+
'<div class="col-sm-1">'+
'<p class="form-control-static">Notes:</p>'+
'</div>'+
'<div class="col-sm-3">'+
'<input type="text" class="form-control" placeholder="Thickness mm / Weight kg">'+
'</div>'+
'<div class="col-sm-4">'+
'<button id="' + num + '" class="btn btn-default removeEquipment"><span class="glyphicon glyphicon-remove"></span></button>'+
'</div>'+
'</div>'+
'</td>';
$div.after($clone.html($equipment));
$('.removeEquiment').bind('click', function(evt) {
var $id = $(evt.target).prop('id');
var $removeEquipment = $('tr[id^="rowEquipment' + $id + '"]');
$removeEquipment.remove();
});
});
这里是图片:
感谢您的任何建议!
编辑:
来自 yergo 的第一个解决方案(谢谢)产生 SyntaxError: invalid property id
,可能是因为 {% for item in equipment %}
现在被视为 JavaScript 而不是字符串。
第二个解决方案,完成后是这样的:
var div = $('tr[id="cloneEquipment"]')[0];
var clone = div.cloneNode();
clone.parentNode.insertBefore(clone, div);
结果 TypeError: clone.parentNode is null
可能要提一下(对不起,我忘了):jQuery 代码在一个单独的 .js 文件中
编辑 2
我犯了一个错误:我试图将其附加到克隆节点的parentNode,这显然是伪造的。现在,我已经这么远了:
基于yergo的第二个解决方案,我在JSFiddle中做了一些try&error。现在我的解决方案如下所示:
var div = $('tr[id^="cloneEquipment"]');
var clone = div.clone();
clone.removeClass('hidden');
var cloneNode = clone[0].cloneNode();
div[0].parentNode.insertBefore(cloneNode, div[0]);
克隆过程似乎有效,但它只克隆 <tr>
而不是其中的内容。
尝试修复此部分:
'<select class="form-control">'+
'<option value="0">No equipment</option>' +
{% for item in equipment %}
'<option value="{{ item.id }}">{{ item.name }}</option>' +
{% endfor %}
'</select>' +
只要这部分代码是在服务器端生成并通过 Volt 引擎解析的,Volt 控制语法就应该受到威胁,因为它不会出现在结果输出中。所以放置 '{% for item in equipment %}'+
是非常有问题的。
此外,您可以使用 JS 克隆整个 DOM 节点。在这个页面上试试这个代码:
var node = $('img[src="http://i.stack.imgur.com/35SUS.png"]')[0];
var nodeClone = node.cloneNode(true); // <- change here to 'true' for deep clone
node.parentNode.insertBefore(nodeClone, node);
您可以将整个 <tr>
保留在隐藏元素中,并使用简单的 JS 为新行克隆它。
编辑:关于clonning:
Tip: Set the deep parameter value to true if you want to clone all descendants (children), otherwise false.
经过反复试验,我得出了以下工作代码。所有 clone.find()
命令都可以忽略。这一直是一个纯粹的 jQuery 问题,与 Volt 或 Phalcon 无关。像这样,正确解析了伏特代码:
$('#addEquipment').bind('click', function() {
var div = $('tr[id^="rowEquipment"]:last');
var num = parseInt(div.prop('id').match(/\d+/g), 10) + 1;
var clone = div.clone();
clone.prop('id', 'rowEquipment' + num);
clone.find('.addEquipment').tooltip('disable');
clone.find('.addEquipment').remove();
clone.find('.helpEquipment').remove();
clone.find('.removeEquipment').prop('id', num);
clone.find('.removeEquipment').removeClass('hidden');
$(div).after(clone);
$('.removeEquipment').bind('click', function(evt) {
var $id = $(evt.target).prop('id');
var $removeEquipment = $('tr[id^="rowEquipment' + $id + '"]');
$removeEquipment.remove();
});
});
这里有一个 JSFiddle 供感兴趣的人使用:
clickerino
我有一个(也许)非常独特的问题。您可以查看下图以便更好地理解。
select 区域中的设备在控制器中获取,然后我用 Volt 循环遍历它们并在 <option>
标签中回显它们,如下面的代码所示:
<select class="form-control">
<option value="0">No equipment</option>
{% for item in equipment %}
<option value="{{ item.id }}">{{ item.name }}</option>
{% endfor %}
</select>
用户可以按加号按钮添加另一个设备。整个 <tr>
被克隆并通过 jQuery 附加。问题是,当我想遍历设备时。伏特代码未被解析,而是被 jQuery 显式回显,如下图所示。
克隆代码是这样的(我想这很老套,不过我不知道有更好的替代方法):
$('#addEquipment').bind('click', function() {
var $div = $('tr[id^="rowEquipment"]:last');
var num = parseInt($div.prop('id').match(/\d+/g), 10) + 1;
var $clone = $div.clone().prop('id', 'rowEquipment' + num);
var $equipment = '<td>'+
'<div class="row">'+
'<div class="col-sm-1">'+
'<p class="form-control-static">Equipment:</p>'+
'</div>'+
'<div class="col-sm-3">'+
'<select class="form-control">'+
'<option value="0">No equipment</option>'+
'{% for item in equipment %}'+
'<option value="{{ item.id }}">{{ item.name }}</option>'+
'{% endfor %}'+
'</select>'+
'</div>'+
'<div class="col-sm-1">'+
'<p class="form-control-static">Notes:</p>'+
'</div>'+
'<div class="col-sm-3">'+
'<input type="text" class="form-control" placeholder="Thickness mm / Weight kg">'+
'</div>'+
'<div class="col-sm-4">'+
'<button id="' + num + '" class="btn btn-default removeEquipment"><span class="glyphicon glyphicon-remove"></span></button>'+
'</div>'+
'</div>'+
'</td>';
$div.after($clone.html($equipment));
$('.removeEquiment').bind('click', function(evt) {
var $id = $(evt.target).prop('id');
var $removeEquipment = $('tr[id^="rowEquipment' + $id + '"]');
$removeEquipment.remove();
});
});
这里是图片:
感谢您的任何建议!
编辑:
来自 yergo 的第一个解决方案(谢谢)产生 SyntaxError: invalid property id
,可能是因为 {% for item in equipment %}
现在被视为 JavaScript 而不是字符串。
第二个解决方案,完成后是这样的:
var div = $('tr[id="cloneEquipment"]')[0];
var clone = div.cloneNode();
clone.parentNode.insertBefore(clone, div);
结果 TypeError: clone.parentNode is null
可能要提一下(对不起,我忘了):jQuery 代码在一个单独的 .js 文件中
编辑 2
我犯了一个错误:我试图将其附加到克隆节点的parentNode,这显然是伪造的。现在,我已经这么远了:
基于yergo的第二个解决方案,我在JSFiddle中做了一些try&error。现在我的解决方案如下所示:
var div = $('tr[id^="cloneEquipment"]');
var clone = div.clone();
clone.removeClass('hidden');
var cloneNode = clone[0].cloneNode();
div[0].parentNode.insertBefore(cloneNode, div[0]);
克隆过程似乎有效,但它只克隆 <tr>
而不是其中的内容。
尝试修复此部分:
'<select class="form-control">'+
'<option value="0">No equipment</option>' +
{% for item in equipment %}
'<option value="{{ item.id }}">{{ item.name }}</option>' +
{% endfor %}
'</select>' +
只要这部分代码是在服务器端生成并通过 Volt 引擎解析的,Volt 控制语法就应该受到威胁,因为它不会出现在结果输出中。所以放置 '{% for item in equipment %}'+
是非常有问题的。
此外,您可以使用 JS 克隆整个 DOM 节点。在这个页面上试试这个代码:
var node = $('img[src="http://i.stack.imgur.com/35SUS.png"]')[0];
var nodeClone = node.cloneNode(true); // <- change here to 'true' for deep clone
node.parentNode.insertBefore(nodeClone, node);
您可以将整个 <tr>
保留在隐藏元素中,并使用简单的 JS 为新行克隆它。
编辑:关于clonning:
Tip: Set the deep parameter value to true if you want to clone all descendants (children), otherwise false.
经过反复试验,我得出了以下工作代码。所有 clone.find()
命令都可以忽略。这一直是一个纯粹的 jQuery 问题,与 Volt 或 Phalcon 无关。像这样,正确解析了伏特代码:
$('#addEquipment').bind('click', function() {
var div = $('tr[id^="rowEquipment"]:last');
var num = parseInt(div.prop('id').match(/\d+/g), 10) + 1;
var clone = div.clone();
clone.prop('id', 'rowEquipment' + num);
clone.find('.addEquipment').tooltip('disable');
clone.find('.addEquipment').remove();
clone.find('.helpEquipment').remove();
clone.find('.removeEquipment').prop('id', num);
clone.find('.removeEquipment').removeClass('hidden');
$(div).after(clone);
$('.removeEquipment').bind('click', function(evt) {
var $id = $(evt.target).prop('id');
var $removeEquipment = $('tr[id^="rowEquipment' + $id + '"]');
$removeEquipment.remove();
});
});
这里有一个 JSFiddle 供感兴趣的人使用: clickerino