简体   繁体   English

使用KnockoutJS创建可重用的组件

[英]Creating reusable components with KnockoutJS

I've been creating reusable components as jQuery plugins for projects for some time now. 我一直在为项目创建可重用的组件作为jQuery插件。 I like being able to abstract away the logic, and inject all of the context (selectors, options, etc) on a case-by-case basis. 我喜欢能够抽象出逻辑,并根据具体情况注入所有上下文(选择器,选项等)。

Now, I'm starting to use KnockoutJS, and have written a nice little jQuery plugin that uses Knockout for its internal logic. 现在,我开始使用KnockoutJS,并编写了一个很好的小jQuery插件,它使用Knockout作为其内部逻辑。 It works quite well, but I'm wondering if there is a better way to do it? 它工作得很好,但我想知道是否有更好的方法来做到这一点? Does Knockout itself have a pattern/convention for creating reusable components, or is this pattern okay? Knockout本身是否有用于创建可重用组件的模式/约定,或者这种模式是否正常?

Here is an example, it should be enough to give you the idea of what I'm doing. 这是一个例子,它应该足以让你知道我在做什么。

/*globals jQuery, knockout */
(function ($, ko) {
    "use strict";
    $.fn.itemManager = function (options) {
        // set up the plugin options
        var opts = $.extend({}, $.fn.itemManager.defaultOptions, options),
            $wrap = $(this),
            templateUrl = '/path/to/template/dir/' + opts.templateName + '.html';

        // set up the KO viewmodel
        function ItemManagerModel(items) {
            var self = this;

            self.items = ko.observableArray(items);
            self.chosenItemId = ko.observable();
            self.chosenItemData = ko.observable();

            // generic method for navigating the Item hierarchy
            self.find = function (array, id) {
              /* ... */
            };

            /* bunch of other stuff... */

            self.goToItem(items[0]);
        }

        // this is where the whole thing starts...
        $(opts.openTriggerSelector).click(function (e) {
            e.preventDefault();

            // set the template html
            $.get(templateUrl, function (data) {
                $wrap.html(data);
            });

            // initial load and binding of the data, in reality I have some more conditional stuff around this...
            // there's probably a better way to do this, but I'll ask in a separate question :)
            $.get(opts.getItemsServiceUrl, function (result) {
                ko.applyBindings(new ItemManagerModel(result), document.getElementById($wrap.attr('id')));
                $wrap.data('bound', true);
            });

            // opens the template, which now is bound to the data in a dialog
            $wrap.dialog({ /* ... */ });

    // provide default plugin options
    $.fn.itemManager.defaultOptions = {
      getItemsServiceUrl: '/path/to/service',
      openTriggerSelector: 'a',
      templateName: 'Default'
    };
} (jQuery, ko));

I run a github project for KO components. 我为KO组件运行了一个github项目。 It's using an older version of KO and is due for a major revamp but you may be able to get some ideas. 它正在使用较旧版本的KO,并且需要进行重大改进,但您可能会得到一些想法。 I basically do it all through custom bindings that take model objects as their configuration and data. 我基本上通过将模型对象作为其配置和数据的自定义绑定来完成所有操作。

I am always on the lookout for a better way of doing this. 我一直在寻找更好的方法来做到这一点。 Keep me posted if you come up with a better way. 如果你想出一个更好的方法,请让我发布。

https://github.com/madcapnmckay/Knockout-UI https://github.com/madcapnmckay/Knockout-UI

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM