在 Knockout 视图模型中调用 jQuery 插件是一种有效模式吗?
Is calling jQuery plugins in a Knockout view model a valid pattern?
我经常创建自定义绑定处理程序来更改 DOM。但有时我会偶然发现我想将这种代码放入 subscribe
处理程序中的情况。
MyModel =
{
this.name = ko.observable();
this.name.subscribe(function()
{
// is it correct to do these kind of calls inside a model?
$.ajax(
{
url: "... url that creates customer on server ...",
success: function()
{
$(".container_element").noty(
{
text: "Customer created!"
});
}
});
});
}
Noty 是一个 jQuery 弹出警报消息的插件,由于 Noty 实际上改变了 DOM,推荐的设计模式是什么?
如果您想在视图模型内部进行DOM操作,通常是一个危险信号[=46] =](有一些例外,最著名的是 the beforeRender
& friends callbacks)。这是因为通常,使用 MVVM 风格的编程,你有一个 View lighty 依赖于 View Model(具有声明性绑定),并且没有依赖关系从您的视图模型到视图。这很好的两个主要原因:
- 您的 VM 未与视图紧密耦合,因此您可以轻松地创建依赖于同一视图模型的不同视图。
- 您的 VM 更容易进行单元测试,因为测试单元不需要 DOM 存在。
你已经提到了,你可能应该使用什么:custom binding handlers。来自相关文档:
This is how to control how observables interact with DOM elements, and gives you a lot of flexibility to encapsulate sophisticated behaviors in an easy-to-reuse way.
我找不到 "Noty" 示例自定义绑定,因此您必须创建自己的(通常并不难)。您可以从 this jQuery UI custom binding 以及文档中获得一些灵感。
使用您的示例将其放入代码中,看起来像这样:
ko.bindingHandlers.noty = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Set up any initial state, event handlers, etc. here
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var value = ko.utils.unwrapObservable(valueAccessor()),
$el = $(element);
if(!!value) { $($el).noty({text: value}); }
}
};
// Mock $.ajax for this example
$.ajax = function(options) { options.success({}); }
MyModel = function()
{
var self = this;
this.name = ko.observable();
this.myAlertMsg = ko.observable("");
this.name.subscribe(function()
{
// is it correct to do these kind of calls inside a model?
$.ajax(
{
url: "... url that creates customer on server ...",
success: function()
{
self.myAlertMsg("Customer created!");
}
});
});
}
ko.applyBindings(new MyModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-noty/2.3.4/packaged/jquery.noty.packaged.min.js"></script>
<div data-bind="noty: myAlertMsg"></div>
<input data-bind="value: name" /> (blur input to finish editing name)
请注意,我们需要 var self = this
习惯用法才能轻松引用 success
回调中的视图模型。
我经常创建自定义绑定处理程序来更改 DOM。但有时我会偶然发现我想将这种代码放入 subscribe
处理程序中的情况。
MyModel =
{
this.name = ko.observable();
this.name.subscribe(function()
{
// is it correct to do these kind of calls inside a model?
$.ajax(
{
url: "... url that creates customer on server ...",
success: function()
{
$(".container_element").noty(
{
text: "Customer created!"
});
}
});
});
}
Noty 是一个 jQuery 弹出警报消息的插件,由于 Noty 实际上改变了 DOM,推荐的设计模式是什么?
如果您想在视图模型内部进行DOM操作,通常是一个危险信号[=46] =](有一些例外,最著名的是 the beforeRender
& friends callbacks)。这是因为通常,使用 MVVM 风格的编程,你有一个 View lighty 依赖于 View Model(具有声明性绑定),并且没有依赖关系从您的视图模型到视图。这很好的两个主要原因:
- 您的 VM 未与视图紧密耦合,因此您可以轻松地创建依赖于同一视图模型的不同视图。
- 您的 VM 更容易进行单元测试,因为测试单元不需要 DOM 存在。
你已经提到了,你可能应该使用什么:custom binding handlers。来自相关文档:
This is how to control how observables interact with DOM elements, and gives you a lot of flexibility to encapsulate sophisticated behaviors in an easy-to-reuse way.
我找不到 "Noty" 示例自定义绑定,因此您必须创建自己的(通常并不难)。您可以从 this jQuery UI custom binding 以及文档中获得一些灵感。
使用您的示例将其放入代码中,看起来像这样:
ko.bindingHandlers.noty = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Set up any initial state, event handlers, etc. here
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var value = ko.utils.unwrapObservable(valueAccessor()),
$el = $(element);
if(!!value) { $($el).noty({text: value}); }
}
};
// Mock $.ajax for this example
$.ajax = function(options) { options.success({}); }
MyModel = function()
{
var self = this;
this.name = ko.observable();
this.myAlertMsg = ko.observable("");
this.name.subscribe(function()
{
// is it correct to do these kind of calls inside a model?
$.ajax(
{
url: "... url that creates customer on server ...",
success: function()
{
self.myAlertMsg("Customer created!");
}
});
});
}
ko.applyBindings(new MyModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-noty/2.3.4/packaged/jquery.noty.packaged.min.js"></script>
<div data-bind="noty: myAlertMsg"></div>
<input data-bind="value: name" /> (blur input to finish editing name)
请注意,我们需要 var self = this
习惯用法才能轻松引用 success
回调中的视图模型。