将 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" 代替克隆您的内容并保留它。这可能更适合您绑定代码的方式。
我正在制作一个 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" 代替克隆您的内容并保留它。这可能更适合您绑定代码的方式。