如何从 DOM 节点转到 viewModel 对象?

Posted

技术标签:

【中文标题】如何从 DOM 节点转到 viewModel 对象?【英文标题】:How to go from DOM node to viewModel object? 【发布时间】:2011-05-19 19:38:34 【问题描述】:

drop 函数被回调时,this 被设置为可放置的 DOM 节点(目标),ui.draggable 为被拖动的 DOM 节点。

是否有一种惯用的方式来获取已呈现为特定 DOM 节点的模型对象?

(如果重要的话,我正在使用 jQuery 模板。单个 modelView 对象可能不止一次呈现。)

【问题讨论】:

【参考方案1】:

可能有更好的方法来做到这一点,但我作弊了。这是我的绑定。

编辑

由于下面的例子不完整,我做了一个简单的完整例子,可以在这里找到。

http://pastie.org/1446229

存储当前拖动元素的位置由您决定。在示例中,我使用全局变量作为 viewModel 项的代理。您可以为每个可拖动对象和可放置对象引用其父模型并以这种方式访问​​属性,这取决于您。

希望这会有所帮助。

ko.bindingHandlers.drag = 
                init: function (element, valueAccessor, allBindingsAccessor, viewModel) 
                    var $element = $(element),
                        dragOptions =  
                            revert: 'invalid',
                            revertDuration: 250,
                            cancel: 'span.handle',
                            cursorAt:  left: 28, bottom: 0 ,
                            appendTo : 'body',
                            helper: function ()  
                                return $('<div class="drag-icon"><img src="images/folder-large.png"    /></div>'); 
                            ,
                            cursor: "pointer",
                            addClasses: false,
                            distance: 10,
                            start : function (e, ui)  
                                viewModel.isDragging();
                            
                        ;

                    $element.draggable(dragOptions);
                ,
                update : function (element, valueAccessor, allBindingsAccessor, viewModel) 
                    var $element = $(element),
                        active = valueAccessor();

                    if (!active) 
                        $element.draggable('disable');
                    
                    else 
                        $element.draggable('enable');
                    
                
            ;

ko.bindingHandlers.drop = 
                init: function (element, valueAccessor, allBindingsAccessor, viewModel) 
                    var $element = $(element),
                        value = valueAccessor() || ,
                        handler = ko.utils.unwrapObservable(value.onDropComplete),
                        dropOptions =  
                            greedy: true,
                            tolerance: 'pointer',
                            addClasses: false,
                            drop: function (e, ui) 
                                setTimeout(function ()  
                                                handler(viewModel.dragging()); 
                                            , 0);
                            
                        ;
                    $element.droppable(dropOptions);
                
            ;

所以我设置了可拖动并在启动函数中存储了当前拖动的节点viewModel.isDragging();,然后我可以在放置处理程序中再次访问它。

干杯,

伊恩

【讨论】:

谢谢,这很有用,但可能不完整。如何获取用于呈现可放置目标的 viewModel 对象?我需要这种交互的两个部分——理想情况下是 DOM 任何部分的“最近的父”viewModel 对象。 您可以访问被拖动的项目 viewModel.dragging()。当一个可拖动对象被放置在放置目标上时,“放置”处理程序就会运行。在这个处理程序中,我可以使用 valueAccessor() 访问绑定的 viewModel 或它的属性。传递给 update/init 的 viewModel 参数是它绑定的项目。 事实上,这里可能还不清楚,但我正在使用已删除的模型元素调用处理程序。 Handler 是绑定中指定的方法(onDropComplete),在作为放置目标绑定的 viewModel 上调用。 您能否举例说明您正在以拖放方式呈现的数据结构。然后我将更新我的示例。 编辑包含一个完整的例子。

以上是关于如何从 DOM 节点转到 viewModel 对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何从屏幕上删除View后立即销毁ViewModel对象

面试官:什么是虚拟DOM?如何实现一个虚拟DOM?

如何理解虚拟dom

DOM(文档对象模型)

html dom中windows对象的4个常用子对象

如何从 ViewModel 对象填充选择器,设置为第一个元素的初始状态并处理选择选择器项的操作