knockout.js变量用作ID

Dal*_*eme 0 javascript web-deployment web knockout.js

我试图遍历一个knockouts数组,每个元素都必须有一个唯一的id.我的数据结构中有一个id,我想用它.如果我展示它可能会更容易.

    <div class="row">      
         <div data-bind="foreach: something">
             <div style="display: none;" class="col-xs-12" data-bind="attr: {id: id}">
                      hidden stuff
             </div>
             <div class="col-xs-1 hidden-menu-trigger-button">
                 <div style=" height:inherit; line-height:6px; cursor:pointer; color:black" onclick="$('#' + $id).slideToggle('slow1', null);"> //problem is I assume here
             </div>      

         </div>

    </div>
Run Code Online (Sandbox Code Playgroud)

所以我相信当我绑定id作为属性是好的但是当我尝试定义onclick事件时,我不知道如何获取id的值.

Tom*_*lak 5

首先,最重要的是:永远不要使用内联事件处理程序.期.onclick="..."从HTML中删除所有可能具有的所有事件属性.

特别是淘汰赛,它可以为您处理所有情况并提供click绑定,您可以使用内联事件处理程序自己动手.

在淘汰之前,在将其转换为视图(即,视觉HMTL表示)之前,拥有一个有效的抽象视图模型非常重要.


在您的情况下,您想要封装项目的可见性.这意味着你需要一个observable,让我们调用它visible,以及一个切换该属性的函数toggleVisible().很简单:

function Something(id) {
    var self = this;

    self.id = ko.observable(id);
    self.visible = ko.observable(false);
    self.toggleVisible = function () {
        self.visible( !self.visible() );
    };
}
Run Code Online (Sandbox Code Playgroud)

您想要的下一件事是在项目的visible属性发生变化时封装动画.这意味着你必须以visible某种方式订阅该属性并使jQuery做到这一点.

最适合此任务的是一个动画元素的自定义绑定处理程序.这也不是太难.我们称之为slideToggle:

ko.bindingHandlers.slideToggle = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var shouldBeVisible = ko.unwrap(valueAccessor());

        // initially, display or hide the element instantly
        $(element)[shouldBeVisible ? "show" : "hide"]();
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var shouldBeVisible = ko.unwrap(valueAccessor());

        // during interactive operation, use transition effect
        $(element)[shouldBeVisible ? "slideDown" : "slideUp"]("fast");
    }
};
Run Code Online (Sandbox Code Playgroud)

我建议您阅读有关自定义绑定处理程序的信息,它们非常有用.


现在我们已将所有活动部件抽象到各自的容器中.让我们在这个主ViewModel中使用它们:

function ViewModel() {
    var self = this;

    self.something = ko.observableArray([
        new Something("id1"),
        new Something("id2")
    ]);
}
Run Code Online (Sandbox Code Playgroud)

而这个观点:

<div class="row">
     <div data-bind="foreach: something">
         <div class="col-xs-12" data-bind="slideToggle: visible">
            hidden stuff
         </div>
         <div class="col-xs-1 hidden-menu-trigger-button">
             <div data-bind="click: toggleVisible">Click Me!</div>
        </div>
     </div>
</div>
Run Code Online (Sandbox Code Playgroud)

注意一切是如何落实到位的,你甚至不需要对元素ID的引用,因为knockout会为你处理上下文.此外,slideToggle动画变得非常容易重复使用,您的视图变得不那么痛苦.