【问题标题】:Where does ui javascript belong in the MVVM model (with knockout)?ui javascript 在 MVVM 模型中属于哪里(带有淘汰赛)?
【发布时间】:2015-02-10 10:54:20
【问题描述】:

假设您从一个通过 jquery 完成 UI 影响的网站开始。例如,菜单。单击锚点会应用一个类来显示锚点是活动锚点。这是在 dom 就绪的 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>

click 事件不会附加到这些项目上,因为 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 模式执行此操作的正确方法是什么?或者用淘汰赛做这件事的正确方法是什么?通过视图模型似乎是最干净的,但它在哪里停止?您是否有 javascript 使其成为 ViewModel 中鼠标悬停时的下拉菜单?

【问题讨论】:

  • 使用委托:$("#menu").on("click", "a", fn)。或将脚本块移动到模板中,以便它们一起更新。
  • 我建议您阅读淘汰赛文档(我知道这不是什么)。我还建议使用敲除事件侦听器,因为它们实现得非常好,您不必担心在它们失去参考后处理东西 - 敲除会为您做到这一点
  • 好问题,因为您有两种技术发生冲突。两者都有能力,而且它们本身都没有违反 MVVM 概念。问题是您想通过数据还是通过 JQUERY UI 控制视图状态?也许您目前在站点中有很多 JQUERY UI,在这种情况下,最好坚持使用它。如果它是一个新站点,那么当您转向真正的数据绑定技术时,也许 KO 更可取! KO功亏一篑;然而,在动画中,JQuery UI 更好。 (海事组织)

标签: javascript mvvm knockout.js


【解决方案1】:

我会向菜单项添加一个 isSelected 可观察对象,然后在单击菜单项时切换它(使用单击绑定)。然后您可以在将使用 isSelected 的视图中使用 css 绑定。

正如您在使用 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/

【讨论】:

  • Wayne 展示了另一个概念,即客户端视图模型。这是 Angular 正在开放的东西,社区似乎正在运行到客户端视图模型、控制器甚至路由。
  • @JohnPeters 这是一个淘汰赛问题而不是 Angular 问题,所以尽量保持话题。本页讨论 MVVM 以及模型、视图和视图模型之间的区别:knockoutjs.com/documentation/observables.html
  • 没有意识到仅仅提到另一个框架就需要受到谴责。这是给你的建议,请忽略我所说的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-30
  • 2014-04-08
  • 1970-01-01
  • 2012-08-08
  • 2013-12-18
  • 2012-06-13
  • 1970-01-01
相关资源
最近更新 更多