假设您开始使用一个通过 jquery 实现 UI 效果的网站。例如菜单。单击 anchor 将对其应用一个类,以显示该 anchor 是事件 anchor 。这是在 dom 准备好的 jquery 中完成的 -
$(function() {
$("#menu a").click(function(){
$("#menu a").removeClass('active');
$(this).addClass('active');
});
});
现在,假设这个菜单是通过 knockout 绑定(bind)动态生成的 -
$(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 模式执行此操作的正确方法是什么?或者说 knockout 的正确方法是什么?通过viewmodel似乎是最干净的,但是它停在哪里呢?您是否有 JavaScript 使其成为 ViewModel 中鼠标悬停时的下拉菜单?
最佳答案
我将向菜单项添加一个 isSelected 可观察对象,然后在单击菜单项时切换该可观察对象(使用单击绑定(bind))。然后您可以在 View 中使用 css 绑定(bind),该 View 将使用 isSelected。
正如你所看到的,当你使用knockout时,最好只与 View 模型交互,而不是像使用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>
关于javascript - ui javascript 属于 MVVM 模型中的哪个位置(带 knockout )?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27431618/