0

我有一个外部模板,它调用 JSON 对象来填写 div 的详细信息。在将所有项目添加到 DOM 之后(希望使用Isotope),我正在努力让一些 jQuery 触发。

理想情况下,我想获得一些关于如何让 Isotope 工作的支持 - 显示项目和单击链接以进行排序和过滤,以及一些一般的 Knockout 帮助。我是 KO 的新手,我什至不确定我在做什么是最佳实践。

这是相关的代码(我不确定让 JSFiddle 与外部模板一起运行 - 如果您有任何提示,我准备提供一个示例!):

如果我将“afterAdd”更改为“afterRender”,Isotope 及其过滤机制将起作用——但它只渲染一个项目——而不是整个对象。

HTML

<div data-bind="template: { name: 'itemList', foreach: sampleItems, afterAdd: renderIsotope }"></div>

外部模板

<div data-bind='attr: { "class": "item " + type }'>
<div class="item-details">
    <span class="type" data-bind="text: type"></span>
    <span class="size" data-bind="text: size"></span>
    <span class="name" data-bind="text: name"></span>
    <!-- ko if: type === 'folder' -->
    <a href="#" class="changeFolderColor">Change Folder Color</a>
    <span class="folderColor" style="display: none" data-bind="text: backgroundColor"></span>
    <!-- /ko -->
</div>

<!-- ko if: type !== 'folder' -->
<img data-bind="attr: { src: preview }" />
<!-- /ko -->

模型

var sampleItems = [    
{
    type: "image",
    size: "2482",
    name: "Robert",
    preview: "/images/placeholders/178x178-1.jpg",
    backgroundColor: "",
    id: "1"
}, ....

视图模型

var itemsModel = function (items) {
    var self = this;
    self.items = ko.observableArray(ko.utils.arrayMap(items, function (item) {
        return { type: item.type, size: item.size, name: item.name, preview: item.preview, backgroundColor: item.backgroundColor, id: item.id };
    }));
}

尝试了“afterAdd”功能

var renderIsotope = function (elements) { 
// initialize isotope
$(".content .right").isotope({
    itemSelector: ".item",
    getSortData: {
        type: function ($elem) {
            return $elem.find(".type").text();
        },
        size: function ($elem) {
            return parseFloat($elem.find(".size").text());
        },
        name: function ($elem) {
            return $elem.find(".name").text();
        }
    }
});

// filter items when filter link is clicked
$('.item-filter a').click(function () {
    var selector = $(this).attr('data-filter');
    $(".content .right").isotope({ filter: selector });
    return false;
});

// sort items when sort link is clicked
$('.item-sort a').click(function () {
    // get href attribute, minus the '#'
    var sortName = $(this).attr('href').slice(1);
    $(".content .right").isotope({ sortBy: sortName });
    return false;
});
}
4

2 回答 2

1

Kncokout 为此目的公开了 afterrender 绑定:

<div data-bind='template: { name: "personTemplate",
                        data: myData,
                        afterRender: myPostProcessingLogic }'> </div>

更多在这里

抱歉没有用同位素来帮助你

于 2013-04-09T15:10:50.500 回答
1

这是我正在使用的自定义绑定。这需要你的 viewModel 有一个 afterInit 函数。这在调用 applyBindings 或 Knockout 绑定模板时触发。视图模型需要一个名为 afterInit 的函数:使用显示模块模式:

myViewModel = function(){
  var afterInitDone = false,
      afterInit = function(){
          // this fires from the custom afterInit binding below
          // set afterInitDone, so if it fires again, we ignore it in the custom binding
          afterInitDone = true;
      };

  return {
    AfterInit: afterInit
  };
};
ko.bindingHandlers.afterInit = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext)      
    {
        //Possible place for the draggables when creating the Editor tool
        //$(element).draggable({ containment: "#content", scroll: false });
        'use strict';
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        'use strict';
        // don't run again if it has already been called
        if (viewModel.afterInitDone !== undefined) {
           if (!viewModel.afterInitDone) {
               viewModel.AfterInit();
           }
        } else {
            viewModel.AfterInit();
        }
    }
};

然后我只是在 html 中绑定到它: <div data-bind="afterInit: true">

见注 4: http: //knockoutjs.com/documentation/template-binding.html

于 2013-04-09T15:18:10.657 回答