使用foreach渲染创建自定义挖空绑定(对于jquery移动列表视图)

时间:2013-04-08 17:29:43

标签: listview knockout.js custom-binding jquery-mobile

使用jquerymobile和knockout,我正在尝试创建一个如下所示的自定义绑定

<ul data-bind="listview: observablearray">
    <li data-bind="text: text"></li>
</ul>

其中listview绑定首先表现为foreach绑定,然后将$(element).listview()应用于它(或$(element).listview('refresh')更新)。

我尝试过以下方式来天真地模仿foreach绑定:

ko.bindingHandlers.listview = {
  init: function (element, valueAccessor) {
    var listview = $(element);
    listview.listview();
  },
  update: function (element, valueAccessor) {
    var listview = $(element);
    setTimeout(function () {
      listview.html('');
      var items = valueAccessor().list;
      var link = valueAccessor().link;
      var text = valueAccessor().text;
      var icon = valueAccessor().icon;
      $.each(ko.utils.unwrapObservable(items) || [], function (i, item) {
        var li = $('<li></li>').css({
          height: '44px'
        })
        var a;
        if (link) {
          a = $('<a href="#"></a>').click(function () {
            link(item)
          });
          li.append(a);
        }
        if (icon) {
          (a || li).append($('<img />').attr('src', icon(item)).addClass('ui-li-icon'));
        }
        if (text) {
          (a || li).append($('<span></span>').text(item[text]));
        }
        listview.append(li);
      });
      listview.listview('refresh')
    }, 0);
  }
};

不幸的是,这不仅是一个不使用模板的糟糕实现,它也是通过init上的错误:

  

未捕获的TypeError:无法读取属性'jQuery19101983379740267992'   未定义的

提前致谢!

2 个答案:

答案 0 :(得分:0)

您可以通过绑定来调用内部敲除绑定。

在你的情况下这应该有用。

ko.bindingHandlers.listview = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var res = ko.bindingHandlers.foreach.init(element, valueAccessor()['listview']);
        $(element).listview();
        return res;
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var res = ko.bindingHandlers.foreach.update(element, valueAccessor()['listview'], allBindingsAccessor, viewModel, bindingContext);
        $(element).listview('refresh');
        return res;
    }
};

自行渲染模板是一项挑战,最好使用内部“模板”绑定。 'foreach'绑定也是如此。查看knockoutjs代码,看看它是如何完成的。

答案 1 :(得分:0)

对我来说,使用动态jQuery Mobile listview的最快捷方式是订阅模型更改,如下所示:

viewModel.products.subscribe(function() {
    jQuery("#productsList").listview("refresh");  
});