使用KnockoutJS创建可重用的组件

时间:2012-03-01 06:14:41

标签: javascript jquery knockout.js

我一直在为项目创建可重用的组件作为jQuery插件。我喜欢能够抽象出逻辑,并根据具体情况注入所有上下文(选择器,选项等)。

现在,我开始使用KnockoutJS,并编写了一个很好的小jQuery插件,它使用Knockout作为其内部逻辑。它工作得很好,但我想知道是否有更好的方法来做到这一点? Knockout本身是否有用于创建可重用组件的模式/约定,或者这种模式是否正常?

这是一个例子,应该足以让你知道我在做什么。

/*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));

1 个答案:

答案 0 :(得分:2)

我为KO组件运行了一个github项目。它正在使用较旧版本的KO,并且需要进行重大改进,但您可能会得到一些想法。我基本上都是通过将模型对象作为其配置和数据的自定义绑定来完成的。

我一直在寻找更好的方法来做到这一点。如果你想出一个更好的方法,请告诉我。

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