我正在构建一个需要一堆打开/关闭标签的移动应用。我正在尝试找到一种方法来使用bindingHandlers来减少代码量。但我似乎想念一些东西。这是我的小提琴。
http://jsfiddle.net/noppanit/4zRrZ/
这就是我所拥有的
<a href="javascript:void(0)" data-bind="click: expandCommentsRatings">Rating
<div style="display:none" data-bind="visible: productCommentsRatingsVisiblity">
<div class="rating" style="width: 85%">3.5 Stars Rating</div>
</div>
</a>
<br/>
<a href="javascript:void(0)" data-bind="click: expandsReviews">Reviews
<div style="display:none" data-bind="visible: productReviewsVisiblity">
<div class="reviews">Reviews</div>
</div>
</a>
var Model = function () {
var productCommentsRatingsVisiblity = ko.observable(false);
var productReviewsVisiblity = ko.observable(false);
var expandCommentsRatings = function (item, event) {
productCommentsRatingsVisiblity(!productCommentsRatingsVisiblity());
if (productCommentsRatingsVisiblity() === false) {
$(event.target).removeClass('expanded');
} else {
$(event.target).addClass('expanded');
}
};
var expandsReviews = function (item, event) {
productReviewsVisiblity(!productReviewsVisiblity());
if (productReviewsVisiblity() === false) {
$(event.target).removeClass('expanded');
} else {
$(event.target).addClass('expanded');
}
};
return {
productCommentsRatingsVisiblity: productCommentsRatingsVisiblity,
productReviewsVisiblity: productReviewsVisiblity,
expandCommentsRatings: expandCommentsRatings,
expandsReviews: expandsReviews
}
};
ko.applyBindings(Model());
如何减少重复,以便我可以将此代码重用于其他ViewModel。我之所以挣扎是因为我不知道如何动态地将productCommentsRatingsVisiblity
或productReviewsVisiblity
传递给allBindings
。你需要知道这个名字才能得到它。
感谢。
答案 0 :(得分:1)
很抱歉对此有迟到的回复,但我有一个使用bindingHandlers的解决方案。
小提琴在这里:http://jsfiddle.net/u3m7m/1/
我遵循了一个创建toggle bindingHandler的策略,如果元素上没有它,则添加指定的类,如果是,则删除该类。实现此目的所需的唯一状态是元素上的类列表,这意味着您可以从模型中删除所有这些状态跟踪可观察对象。事实上,这是我使用的模型:
var Model = function () {
// stuff
};
ko.applyBindings(Model());
toggle bindingHandler如下所示:
ko.bindingHandlers['toggle'] = {
init: function (element, valueAccessor) {
var value = ko.unwrap(valueAccessor()),
clickHandler = function (e) {
if (!e) {
e = window.event;
}
e.cancelBubble = true;
if (e.stopPropagation) {
e.stopPropagation();
}
var classes = (this.className||'').split(' '),
index = classes.indexOf(value);
if (index >= 0) {
classes.splice(index, 1);
} else {
classes.push(value);
}
element.className = classes.join(' ');
};
element.onclick = clickHandler;
if (element.captureEvents) {
element.captureEvents(Event.CLICK);
}
}
};
希望不会太复杂,e
对象的奇怪外观来自此处:http://www.quirksmode.org/js/introevents.html
因为我使用的是仅使用类的策略,所以我必须添加到CSS中:
.expandable > div
{
display: none;
}
.expandable.expanded > div
{
display: block;
}
现在从html中删除了状态跟踪,并修改了data-bind
以使用toggle
bindingHandler:
<a class="expandable" href="javascript:void(0)" data-bind="toggle: 'expanded'">Rating
<div>
<div class="rating" style="width: 85%">3.5 Stars Rating</div>
</div>
</a>
<br/>
<a class="expandable" href="javascript:void(0)" data-bind="toggle: 'expanded'">Reviews
<div>
<div class="reviews">Reviews</div>
</div>
</a>
希望这对你有所帮助。
答案 1 :(得分:0)
我不确定这会对你有所帮助,
我根据您的需要重建和优化您的代码。
这可能会给你一些想法。您不需要自定义绑定处理程序来实现此功能。
这里有工作的jsFiddle:http://jsfiddle.net/farizazmi/6E4Wz/2/
所以,您需要包含属性来控制项目的可见性:
var data = [
{
'name' : 'test1',
'rateIsExpanded' : ko.observable(false),
'rating': 3.5,
'review': 'blabla1',
'reviewIsExpanded': ko.observable(false)
},
{
'name' : 'test2',
'rateIsExpanded' : ko.observable(false),
'rating': 1.5,
'review': 'blabla2',
'reviewIsExpanded': ko.observable(false)
}
];
并创建一个函数将用于改变每个数据的可见性状态:
var Model = function () {
var self = this;
self.data = ko.observableArray(data);
self.expandRate = function(item)
{
console.log(ko.toJSON(item));
item.rateIsExpanded( ! item.rateIsExpanded() );
};
self.expandReview = function(item)
{
item.reviewIsExpanded( ! item.reviewIsExpanded() );
};
};
ko.applyBindings(Model());
答案 2 :(得分:0)
您只需使用observableArray
来保存您的菜单系统,即可使用以下属性执行此操作:
itemName
- 保存顶级菜单项expanded
- 控制带子项目的子菜单的扩展subMenu
- 举行儿童用品除此之外,您需要一个简单的功能来在单击父级时切换每个子菜单的可见性。然后,您可以在数据绑定中使用knockout visible
属性,该属性将绑定到expanded
属性。
这是一个有用的 JSFiddle ,以下是使用的代码:
JS查看模型:
var Model = function () {
var self = this;
self.tabs = ko.observableArray([
{ itemName: "Ratings",
expanded: ko.observable(false),
subMenu: ["option 1","option 2"]},
{ itemName: "Review",
expanded: ko.observable(false),
subMenu: ["option 1","option 2"]}
]);
self.toggleExpanded = function (item) {
item.expanded(!item.expanded());
}
};
ko.applyBindings(Model());
HTML Mark Up:
<ul data-bind="foreach: tabs">
<li><span data-bind="text: itemName, click: toggleExpanded"></span>:
<ul data-bind="foreach: subMenu">
<li data-bind="text: $data, visible: $parent.expanded">
</li>
</ul>
</li>
</ul>