【问题标题】:where to write dom manipulation code when using knockout and MVVM part 2使用淘汰赛和 MVVM 第 2 部分时在哪里编写 dom 操作代码
【发布时间】:2013-07-30 18:33:48
【问题描述】:

大家好,我昨天向question 询问了使用淘汰赛时在哪里编写 dom 操作/动画等。我之前已将其编码到视图模型中,并被告知这是不正确的。

我现在更新了我的代码并按照建议创建了自定义绑定处理程序,但是我需要从自定义绑定处理程序中调用我的视图模型的方法。特别是当动画完成时。我已经这样做了

ko.bindingHandlers.slideUp = {
    init:function(element, valueAccessor, allBindingsAccessor, context){
        var allBindings = allBindingsAccessor();
        var parent = allBindings.parent;

        $(element).click(function(){
            if(parent.SelectedEmployee() === valueAccessor())return;

            var $PanelWrapper = $('#' + allBindings.panelName); 
            var $Bottom = parseInt($PanelWrapper.css("bottom"));

            if($Bottom === 0){
                $PanelWrapper.animate({
                    bottom:"-95"
                }, 500, function(){
                    parent.Select(valueAccessor());
                }).animate({
                    bottom:"0"
                }, 500);
            }else{
                parent.Select(valueAccessor());

                $PanelWrapper.animate({
                    bottom:"0px"
                }, 500);       
            }
        });
    }
}

我的绑定是

<tbody data-bind="foreach: Emps">
            <tr data-bind="slideUp: $data, parent: $parent, panelName: 'PanelWrapper'">
                <td data-bind="text: Name"></td>
            </tr>
        </tbody>

正如你所看到的,我传入了对视图模型的引用以及我想要动画的标签的 id。我只是想知道这是否是正确的方法。有没有更好的方法来引用视图模型,我是否正确调用了视图模型的方法,是否可以传入我想要使用的 html 标记的 id。一切正常,但我渴望改进

这是我的fiddle的链接

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    您现在将绑定应用到包含员工的元素。我认为将SelectedEmployee observable 应用于#PanelWrapper 会更好,这样您就可以根据SelectedEmployee 的值显示/隐藏它:

    <div id="PanelWrapper" data-bind="EmployeePanel: $root.SelectedEmployee"></div>
    

    然后你的 JS:

    ko.bindingHandlers.EmployeePanel = {
        currentEmployee: null,
        init: function(element, valueAccessor) {
            var value = valueAccessor();
            this.setEmployee(element, ko.utils.unwrapObservable(value));
        },
        update: function(element, valueAccessor) {
            var value = valueAccessor();
            this.setEmployee(element, ko.utils.unwrapObservable(value));
        },
        setEmployee: function(element, value) {
            if (value === currentEmployee) return; // already selected employee
            this.currentEmployee = value;
            if (value) {
                $(element).fadeIn(); // show and populate the panel here
            } else {
                $(element).fadeOut(); // hide the panel here
            }
        }
    };
    

    所以现在您的员工行将如下所示:

    <tr data-bind="click: $root.OnEmployeeClick">
    

    还有你的ViewModel

    self.OnEmployeeClick = function(employee) { self.SelectedEmployee(employee); };
    

    【讨论】:

    • 顺便说一句,您可以更新@Richard fiddle 示例并将其与您的代码一起发布。
    • 我知道,但他只是想知道他的方法是否好/可以改进。我的代码未经测试,必须针对他的案例完成,但我相信他在实现它时不会有任何问题。
    猜你喜欢
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 2013-04-28
    • 2012-06-13
    • 1970-01-01
    • 2011-09-24
    相关资源
    最近更新 更多