Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jsViews$.observable(arr).insert()未触发DOM更新_Javascript_Jquery_Dom_Jsviews - Fatal编程技术网

Javascript jsViews$.observable(arr).insert()未触发DOM更新

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

我正在使用$.observearray.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方法包装在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);