Javascript jsViews$.observable(arr).insert()未触发DOM更新
我正在使用$.observearray.insert将项目附加到列表中。这是在更新我的视图:新的列表项被呈现到DOM中。但是,我想在新的DOM节点上发出一个click事件,我依赖该事件添加一个类来扩展该项,并将另一个侦听器附加到主体,以便关闭该区域 我两者都试过了Javascript jsViews$.observable(arr).insert()未触发DOM更新,javascript,jquery,dom,jsviews,Javascript,Jquery,Dom,Jsviews,我正在使用$.observearray.insert将项目附加到列表中。这是在更新我的视图:新的列表项被呈现到DOM中。但是,我想在新的DOM节点上发出一个click事件,我依赖该事件添加一个类来扩展该项,并将另一个侦听器附加到主体,以便关闭该区域 我两者都试过了 $.observable(_model.leadTimes).insert(leadTime); $leadTimes.find('.lead-time-data').last().find('.start-editing').cli
$.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方法包装在setTimeOut中,比如setTimeoutfunction{$leadTimes.find'.leadtime data'.last.find'.start editing'.click;},400;,它们都不起作用;,它确实起作用了,这让我相信这是一个时间问题,DOM呈现在调用jQuery click方法之前没有完成
既然你很有可能看到这个,Borris,谢谢你的图书馆和你所做的一切!我认为jsViews是单片框架和普通的老jQuery noodling之间的一个极好的中间地带
2017年9月2日编辑
事实证明,我的问题是重叠的单击事件——我无意中处理了一次单击,以便在选中元素后立即取消选择该元素。然而,我利用这个机会,按照Borris的链接示例,重写了一些内容,使用了一种更具声明性的方法
现在,在我的模板中,我使用一个计算的可观察对象isSelected来切换.editing类:
{^{for leadTimes}}
<tr class="lead-time-data" data-link="class{merge:~isSelected() toggle='editing'}">
<span>{^{:daysLead}}</span>
</tr>
{{/for}}
可观测插入法是同步的。如果列表项仅使用{^{for}}呈现,那么这也是同步的,因此不需要使用setTimeout或回调。有这样的回调可用,但在这种情况下不需要它们
参见示例代码:
将在新插入的项目上同步添加所选内容
渲染中是否有其他异步代码
顺便说一句,如果使用委托模式,通常不需要向添加的元素添加新的单击处理程序。例如,在同一个示例中,删除电影的单击处理程序最初使用委托选择器添加到容器movieList中。removeMovie请参阅。这甚至适用于以后添加的电影
相同的场景使用{{on}}}See工作:选择器参数可以针对稍后添加的元素感谢您的指导;我会调查的!我要添加/删除的单击事件位于主体上。我的想法是在新项目上触发一个单击事件,以便它在被添加时展开,用户可以在主体上单击外部以关闭它。我正在研究一种更具声明性的方法,类似于您上面链接的示例。
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"]};
$.observable(movies).insert({...});
// Set selection on the added item
app.select($.view(".movies tr:last").index);