首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在KnockoutJs中使用bindingHandlers

如何在KnockoutJs中使用bindingHandlers
EN

Stack Overflow用户
提问于 2014-05-30 05:56:02
回答 3查看 277关注 0票数 0

我正在构建一个移动应用程序,它需要一堆打开/关闭选项卡。我试图找到一种使用bindingHandlers来减少代码数量的方法。但我好像错过了什么。这是我的小提琴。

http://jsfiddle.net/noppanit/4zRrZ/

这就是我所拥有的

代码语言:javascript
复制
<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中。我之所以挣扎,是因为我不知道如何动态地将productCommentsRatingsVisiblityproductReviewsVisiblity传递给allBindings。你需要知道名字才能得到它。

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-06-04 00:07:11

很抱歉,这个问题的答复太晚了,但是我有一个使用bindingHandlers的解决方案。

小提琴在这里:http://jsfiddle.net/u3m7m/1/

我遵循了创建切换bindingHandler的策略,如果指定的类不存在于元素中,则添加指定的类;如果存在,则删除该类。实现这一目标所需的唯一状态是元素上的类列表,这意味着您可以从模型中删除所有状态跟踪可观察到的状态。事实上,这就是我使用的模型:

代码语言:javascript
复制
var Model = function () {
   // stuff
};

ko.applyBindings(Model());

切换bindingHandler如下所示:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
.expandable > div
{
    display: none;
}

.expandable.expanded > div
{
    display: block;
}

状态跟踪现在从html中删除,data-bind被修改为使用toggle bindingHandler:

代码语言:javascript
复制
<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
EN

Stack Overflow用户

发布于 2014-05-30 08:24:24

我不确定这能帮到你,

我根据你的需要重构和优化了你的代码。

这可能会给你一些想法。您不需要自定义绑定处理程序来实现这一点。

这里工作的jsFiddle:http://jsfiddle.net/farizazmi/6E4Wz/2/

因此,您需要的是包含属性来控制项的可见性:

代码语言:javascript
复制
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)
    }
];

并创建一个函数,用于更改每个数据的可见性状态:

代码语言:javascript
复制
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());
票数 0
EN

Stack Overflow用户

发布于 2014-05-30 09:16:32

您可以简单地使用observableArray来保存菜单系统,并具有以下属性:

  • itemName -保存顶级菜单项
  • expanded -控制带有子项的子菜单的扩展
  • subMenu -保存子项

最重要的是,当单击父菜单时,需要一个简单的函数来切换每个子菜单的可见性。然后,您可以在数据绑定中使用剔除的visible属性,该属性将绑定到expanded属性。

下面是一个工作的JSFiddle,下面是使用的代码:

JS视图模型:

代码语言:javascript
复制
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标记:

代码语言:javascript
复制
<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>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23947972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档