javascript - 在 Knockout View 模型中调用 jQuery 插件是有效模式吗?

标签 javascript jquery knockout.js

我经常创建更改 DOM 的自定义绑定(bind)处理程序。但有时我会偶然发现一种情况,我想将此类代码放入 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,所以推荐的设计模式是什么?

最佳答案

如果您想要在 View 模型内进行 DOM 操作,那么这通常是一个危险信号(有一些异常(exception),最值得注意的是 the beforeRender & friends callbacks )。这是因为,通常,使用 MVVM 风格的编程,您的 View 轻度依赖于 View 模型(具有声明性绑定(bind)),并且 View 模型与 View 之间没有依赖关系。看法。这很好的两个主要原因:

  1. 您的虚拟机与 View 的耦合并不紧密,因此您可以轻松创建依赖于同一 View 模型的不同 View 。
  2. 您的虚拟机更容易进行单元测试,因为测试单元不需要存在 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”示例自定义绑定(bind),因此您必须创建自己的绑定(bind)(通常并不难)。您可以从 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 回调中的 View 模型。

关于javascript - 在 Knockout View 模型中调用 jQuery 插件是有效模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28779538/

相关文章:

javascript - 可以在webview中使用JS在FBMessenger扩展中获取用户的照片吗?

javascript - 如何将从 fetch 请求检索到的对象添加到 React 中的状态数组,然后更新 View ?

javascript - 在javascript中将代码作为函数参数传递?

javascript - 在 jspdf 中没有获得所需的输出

javascript - 无法获取文本区域值

knockout.js - 如何使用 "Show more..."按钮部分显示 observableArray

javascript - 尝试管理从 API 获取的未定义值 - React

html - 如何使 div 的整个区域都可以点击,同时排除该区域顶部的复选框?

jquery - Knockoutjs 动态模板并将 jquery 效果应用于可见性过渡

javascript - 如何使用 jQuery 附加元素、其所有子元素以及父元素和子元素的所有类