将 KnockoutJS 与 JQuery 灯箱一起使用

Using KnockoutJS with JQuery lightbox

我正在制作一个 KnockoutJS 应用程序,应该可以在其中查看产品,当单击它们时,应该向用户显示所选产品的详细视图,并且应该在其他产品上叠加。

我已经设法使用 JQuery 和 Featherlight.js 完成了几乎所有这些工作。我能够使用 KnockoutJS 可观察变量填充详细视图,但我遇到的问题是,当显示详细视图(使用 JQuery)时,与 KnockoutJS 视图模型的绑定丢失。我希望能够在详细视图中使用 KnockoutJS 收听点击事件(并在下面的代码中调用 knockout 控制器中的函数 "update()")并根据此事件更新视图,但截至目前只有使用 JQuery 才有可能。

我认为问题在于,当使用 Featherlight.js 打开详细视图时,会创建一个新的 "context" 或实例,Knockout 不再具有任何绑定。任何人都知道如何解决这个问题?

这是一个fiddle:https://jsfiddle.net/d1txamd4/8/

这是我的代码:

HTML

<div style="margin-top:2em;" class="row" data-bind="foreach: products">
                   <div class="col l4 m6 s12">
        <div class="card">
            <a href="#" data-bind="click: $parent.showProductDialog">
                <div class="card-image">
                  <img data-bind="attr:{src: image}">
                </div>
            </a>
            <div class="card-content">
              <b data-bind="text: title"></b>
            </div>
            <div class="card-action">
              <p style="float:left;"><span data-bind="text: price"></span> kr</p>
              <a style="float:right;" class="btn disabled">Föreslå</a>
            </div>
        </div>
    </div>
    </div>

<!-- This is the HTML for the lightbox -->
<div class="lightbox">
 <div class="lightbox-content">
      <img data-bind="attr:{src: lightboxImage}"></br>
      <b class="dialog-title" data-bind="text: lightboxTitle"></b>
      <p data-bind="text: lightboxDescription"></p>
 </div>
    <div class="modal-footer">
        <a data-bind="click: update" class="btn">Click me</a>
    </div>
</div>

JavaScript

function ProductCardViewModel() {
    var self = this;

    // Array containing all products
    self.products = ko.observableArray();

    self.lightboxImage = ko.observable();
    self.lightboxDescription = ko.observable();
    self.lightboxTitle = ko.observable();

   self.products = [
       {"id":1,"name":"Cool healine","title":"It's cool to have a cool headline","description":"This text is suppost to describe something","price":700,"image":"http://www.swedishevent.se/se/wp-content/uploads/2010/11/takvandring_top.jpg","categories":[1,4]},{"id":2,"name":"Even cooler headline","title":"A nice headline is the key to success ","description":"What to write, what to write, what to write?","price":500,"image":"http://www.karlliesilva.com/Massage-Therapy-white-flower2.jpg","categories":[2]}
   ];

   self.showProductDialog = function(product) {
        self.lightboxImage(product.image);
        self.lightboxDescription(product.description);
        self.lightboxTitle(product.title);
        $.featherlight('.lightbox');

   };

    <!-- I want to be able to call this function from the lightbox -->
    self.update = function() {
        alert("Success!");
    };
}

ko.applyBindings(new ProductCardViewModel());

这里有两个问题。

一期

featherlight 插件似乎可以创建新的 dom 元素,然后将它们插入 dom。这意味着 knockout 不会绑定到这些注入的元素。

问题二

submit 绑定仅在 form 元素内有效,请参阅 knockout documentation

解决方法

解决方案是两个使用 ko.applyBindings 将视图模型绑定到注入的 dom 元素并将 submit 绑定更改为 点击绑定。

我已经用有效的解决方案更新了您的 fiddle

查看版本 1.3.0 中引入的选项 persist

Featherlight 可以 "steal" 代替克隆您的内容并保留它。这可能更适合您绑定代码的方式。