我使用$ .observable(array).insert()将项目附加到列表中。这正在更新我的视图:新的列表项呈现给DOM。但是,我想在新的DOM节点上发出一个click事件(我依靠事件添加一个类来扩展项目并将另一个监听器附加到正文,以便可以关闭该区域。)
我试过了两次
$.observable(_model.leadTimes).insert(leadTime);
$leadTimes.find('.lead-time-data').last().find('.start-editing').click();
...和
function watchLeadTimes() {
var changeHandler = function (ev, eventArgs) {
if (eventArgs.change === 'insert') {
$leadTimes.find('.lead-time-data').last().find('.start-editing').click();
}
};
$.observe(_model.leadTimes, changeHandler);
}
他们都没有工作,然而,如果我将jQuery方法包装在setTimout中,如setTimeout(function () { $leadTimes.find('.lead-time-data').last().find('.start-editing').click(); }, 400);
, 工作,让我相信这是一个时间问题,在我的jQuery click()方法被调用之前,DOM渲染在某种程度上没有完成。
由于赔率很高,你会看到这个,Borris,谢谢你的图书馆以及你所做的一切!我认为jsViews是那些单片框架和普通的旧jQuery noodling之间的绝佳中间地带!
编辑02/09/17
事实证明我的问题是重叠的点击事件 - 我无意中处理了一个点击,在选中后立即取消选择我的元素。然而,我借此机会重写了一些东西,以便在Borris的链接示例之后使用更具说明性的方法。
现在在我的模板中,我使用一个计算的observable isSelected
来切换.editing类:
{^{for leadTimes}}
<tr class="lead-time-data" data-link="class{merge:~isSelected() toggle='editing'}">
<span>{^{:daysLead}}</span>
</tr>
{{/for}}
这个JS:
function addNewLeadTimeClickHandler() {
var onNewLeadTimeClick = function () {
e.stopPropagation(); // this is what I was missing
var leadTime = {
daysLead: 1,
description: ''
};
$.observable(_model.activityMapping.leadTimes).insert(leadTime);
selectLeadtime(_model.activityMapping.leadTimes.length -1);
}
$leadTimes.on('click', '.add', onNewLeadTimeClick);
}
function selectLeadtime(index) {
var addStopEditingClickHandler = function () {
var onClickHandler = function (event) {
if ($(event.target).closest('tr').hasClass('editing')) {
setHandler();
return;
}
selectLeadtime(-1)
};
function setHandler() {
var clickEvent = 'click.ActivityChangeRequestDetailController-outside-edit-row';
$('html:not(.edit)').off(clickEvent).one(clickEvent, onClickHandler);
};
setHandler();
}
if (_model.selectedLeadtimeIndex !== index) {
$.observable(_model).setProperty('selectedLeadtimeIndex', index)
addStopEditingClickHandler();
}
}
function isSelected() {
var view = this;
return this.index === _model.selectedLeadtimeIndex;
}
// isSelected.depends = ["_model^selectedLeadtimeIndex"];
// for some reason I could not get the above .depends syntax to work
// ...or "_model.selectedLeadtimeIndex" or "_model.selectedLeadtimeIndex"
// but this worked ...
isSelected.depends = function() {return [_model, "selectedLeadtimeIndex"]};
答案 0 :(得分:1)
可观察的insert()
方法是同步的。如果只使用{^{for}}
呈现列表项,那么这也是同步的,因此您不需要使用setTimeout或回调。 (有这样的回调可用,但在这种情况下你不应该需要它们。)
请参阅示例http://www.jsviews.com/#samples/editable/tags(代码here):
$.observable(movies).insert({...});
// Set selection on the added item
app.select($.view(".movies tr:last").index);
选择将在新插入的项目上同步添加。
你的渲染中是否有其他异步代码?
通常,如果使用委托模式,则通常不需要向添加的元素添加新的单击处理程序。例如,在同一个示例中,删除电影的点击处理程序最初会添加到容器"#movieList"
,并带有委托选择器".removeMovie"
(请参阅code)。即使是后来添加的电影,这也适用。
相同的方案使用{{on}}
,请参阅http://www.jsviews.com/#link-events:“选择器参数可以定位稍后添加的元素”