ui javascript在MVVM模型中的位置(使用淘汰赛)?

时间:2014-12-11 20:14:53

标签: javascript mvvm knockout.js

假设您从一个通过jquery完成UI影响的网站开始。例如a,菜单。单击锚点将对此应用类以显示锚点是活动锚点。这是在dom ready上的jquery中完成的 -

$(function() {
  $("#menu a").click(function(){
           $("#menu a").removeClass('active');   
           $(this).addClass('active');
      });
});

现在,假设此菜单是使用敲除绑定动态生成的 -

$(function() {
      $("#menu a").click(function(){
               $("#menu a").removeClass('active');   
               $(this).addClass('active');
          });

    ko.applyBindings();

});

<ul id="menu" data-bind="foreach: menuItem">
    <li>
        <a data-bind="text: menuText"></a>
    </li>
</ul>

点击事件不会附加到这些项目,因为ko.applyBindings在dom准备就绪时发生。我知道像AfterRender这样的事件可以用来解决这个问题,但使用ViewModel看起来更干净 -

<ul data-bind="foreach: menuItem">
        <li>
            <a data-bind="text: menuText, 
                          click:setActive, css: {active: someComputed }"></a>
        </li>
    </ul>

使用MVVM模式执行此操作的正确方法是什么?或者用淘汰赛做这个的正确方法是什么?通过viewmodel似乎是最干净的,但它在哪里停止?你有没有javascript使它成为ViewModel中鼠标悬停的下拉菜单?

1 个答案:

答案 0 :(得分:1)

我会在菜单项中添加一个isSelected observable,然后在单击菜单项时切换(使用单击绑定)。然后你可以在视图中使用css绑定,它将使用isSelected。

正如您所看到的,当您使用knockout时,最好只与视图模型交互,而不是像使用jQuery那样与dom交互。

var ViewModel = function () {
    var self = this;

    self.menuItems = [
        new MenuItem('Text1'),
        new MenuItem('Text2'),
        new MenuItem('Text3'),
        new MenuItem('Text4')
    ];

    self.toggleMenuItem = function (menuItem) {
        for (var i = 0; i < self.menuItems.length; i++) {
            self.menuItems[i].isSelected(false);
        }
        menuItem.isSelected(true);
    };
};

var MenuItem = function (menuText) {
    var self = this;

    self.menuText = menuText;
    self.isSelected = ko.observable(false);
};

<ul id="menu" data-bind="foreach: menuItems">
    <li>
        <a data-bind="text: menuText, click: $parent.toggleMenuItem, css: { active: isSelected }"></a>
    </li>
</ul>

http://jsfiddle.net/d625vaad/1/