【问题标题】:Pass a ViewModel to Reusable Knockout Control将 ViewModel 传递给可重用的敲除控件
【发布时间】:2012-07-10 13:05:38
【问题描述】:

我有一个可重复使用的控件/自定义绑定和模板,旨在基于一组传入的配置选项和最终绑定到页面的 ViewModel 构建一个动态向导。我已经正确构建了向导并显示了所有必填字段,但到目前为止,我一直无法显示要显示的实际输入字段值。

有什么想法吗?

视图模型

var user = function () {
            var self = this;
            self.FirstName = ko.observable("Brent");
            self.LastName = ko.observable("Pabst");
            self.Email = ko.observable("me@brentpabst.com");
            self.FullName = ko.computed(function () {
                return self.FirstName() + " " + self.LastName();
            });
        };

        var tenant = function () {
            var self = this;

            self.Name = ko.observable("Tenant Name");
            self.SubDomain = ko.observable("Sub Domain");
            self.User = ko.observableArray([new user]);

            self.wizardModel = new merlin.wizard({
                title: "Add a Tenant",
                model: self,
                steps: [
                    { Title: "Tenant Information",
                        Fields: [
                            { Name: "Name", Label: "Organization Name", Value: "Name" },
                            { Name: "SubDomain", Label: "Login Page", Value: "SubDomain" }
                        ]
                    },
                    { Title: "Administrator Information",
                        Fields: [
                            { Name: "FirstName", Label: "First Name", Value: "User.FirstName" },
                            { Name: "LastName", Label: "Last Name", Value: "User.LastName" },
                            { Name: "Email", Label: "E-Mail Address", Value: "User.Email" }
                        ]
                    }
                ]
            });

            self.save = function () {
                alert(ko.toJSON(self));
            };
        };

        ko.applyBindings(tenant());

向导模型

    merlin.wizard = function (config) {
    var self = this;
    self.steps = config.steps;
    self.title = config.title;
    self.model = config.model;
    self.currentStep = ko.observable(0);
};

模板和绑定

var templateEngine = new ko.nativeTemplateEngine();

templateEngine.addTemplate = function (templateName, templateMarkup) {
    document.write("<script type=\"text/html\" id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
};

templateEngine.addTemplate("merlin_wizard", "\
    <form class=\"m-ui-wizard\">\
        <h1 data-bind=\"text: title\" />\
        <h2 data-bind=\"text: title\" />\
        <div class=\"m-ui-wizard-steps\" data-bind=\"foreach: steps\">\
            <div class=\"m-ui-wizard-step\">\
                <!-- ko if: $data.Fields -->\
                    <!-- ko foreach: Fields -->\
                        <label data-bind=\"text: Label, attr: { for: Name }\"></label>\
                        <input type=\"text\" data-bind=\"attr: { name: Name }, Value: typeof value === 'function' ? Value($root.model) : $root.model[Value]\" />\
                    <!-- /ko -->\
                <!-- /ko -->\
            </div>\
        </div>\
    </form>");

ko.bindingHandlers.wizard = {
    init: function () {
        return { controlsDescendantBindings: true };
    },
    update: function (element, viewModelAccessor, allBindingsAccessor) {
        var viewModel = viewModelAccessor(), allBindings = allBindingsAccessor();

        while (element.firstChild)
            ko.removeNode(element.firstChild);

        var wizTemplateName = allBindings.gridTemplate || "merlin_wizard";

        var wizContainer = element.appendChild(document.createElement("DIV"));
        ko.renderTemplate(wizTemplateName, viewModel, { templateEngine: templateEngine }, wizContainer, "replaceNode");
    }
};

HTML 片段

<div data-bind="wizard: wizardModel"></div>

注意:我一直无法让它在 Fiddle 中工作,除了我可能会通过这个设置推动 Fiddle 的界限之外,我不知道为什么。

【问题讨论】:

  • 我怀疑你是在“突破 Fiddle 的界限”。当我尝试在小提琴中运行它时,我得到了错误。在关于缺少“nodeType”的淘汰赛中。
  • @Tyrsius 好的,那么有什么想法吗?
  • 我没有再花时间在上面了。我只是指出你的小提琴失败与你“推动小提琴的界限”关系不大,更多的是与语法错误有关。
  • @Tyrsius 是的,语法错误似乎来自两个地方,使用的全局变量以及反斜杠行终止符方法。在 Fiddle 中运行 JSLint 只会显示那些我无法摆脱的错误。

标签: jquery knockout.js custom-component knockout-2.0


【解决方案1】:

&lt;input&gt; 的值绑定字符串不正确。它应该更像:

value: typeof Value === 'function' ? Value($root.model) : $root.model[Value]

这里是a fiddle

【讨论】:

  • 这非常接近,但子对象“用户”的值并没有在你正确的处理中出现。知道为什么吗?
  • 因为 1) User 是一个 observableArray,所以你需要 User()[0].FirstName。 2)更重要的是,您不能仅使用一对括号访问子对象属性。如果值为“User.FirstName”,则 $root.model[Value] 将是 $root.model["User.FirstName"],但模型没有名为 User.FirstName 的属性。您需要拆分该字符串,或者找到另一种方法来处理您的跨对象引用
  • 很好的答案。感谢您的帮助。
猜你喜欢
  • 2016-10-08
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 2013-12-11
  • 1970-01-01
相关资源
最近更新 更多