如何让Knockout从隐藏输入中读取值

时间:2015-12-29 19:53:00

标签: knockout.js asp.net-mvc-5

我的MVC应用程序中有一个隐藏输入的表单,我希望Knockout读取它的值。不幸的是,Knockout中的可观察函数用括号中指定的任何值替换DOM中的原始值,以便

self.title = ko.observable()

将隐藏输入的值更改为空白。如果我有一个用户需要填写的空白表单,那就不会那么糟糕了。我在Stackoverflow上找到了一些使用复杂自定义绑定的答案,但我只是拒绝相信这个简单的东西需要这么复杂的解决方案。 Knockout是否有本地方式:

  1. 从DOM
  2. 中读取输入的EXISTING值
  3. 绑定EXISTING值而不先用它替换它们 初始值?
  4. 这是DOM:

    <div class="form-group has-success">
                    <input type="hidden" id="title" value="@RazorFunction('Title')" data-bind="value:title" />
                    <label class="control-label" for="message">@RazorFunction('Label')</label>
                    <textarea class="form-control" placeholder="@RazorFunction('Placeholder')" rows="5" cols="50" data-bind="value:message"></textarea>
                    <br />
                    <button class="btn btn-primary" data-bind="click:sendMessage">@RazorFunction('Send')</button>
                </div>
    

    这是我在.js文件中的模型:

    var Model = function () {
            var self = this;
            self.message = ko.observable("")
            self.title = ko.observable()
            self.messages = ko.observableArray()
        };
    

2 个答案:

答案 0 :(得分:2)

  

我的MVC应用程序中有一个隐藏输入的表单,其值我想要被Knockout读取。

这完全是错误的想法。 Knockout 从模型生成用户界面(即视图),它不会从用户界面生成模型。

  

不幸的是,Knockout中的observable函数用括号中指定的任何值替换DOM中的原始值,以便

这正是应该发生的事情。用户界面反映了模型所指示的内容。

这里的问题是:为什么视图的某些部分与您的数据模型不对应?纠正这个问题就会解决。

对于基于淘汰的应用程序,带有值的隐藏输入是完全不必要的。如果服务器知道它需要传输到客户端的值,则不要将其写入HTML。创建/发送包含模型初始化所需的所有值的JSON,让Knockout完成整个UI创建,抵制使用Razor视图创建动态UI的冲动。

以下是视图应该是什么样的(让Razor进行国际化,这很好):

<div class="form-group has-success">
  <!-- title is already part of the model, no need to put it in the view
       unless it actually shows up anywhere -->
  <label class="control-label" for="message">@RazorFunction('Label')</label>
  <textarea class="form-control" placeholder="@RazorFunction('Placeholder')" rows="5" cols="50" data-bind="value:message"></textarea>
  <br />
  <button class="btn btn-primary" data-bind="click:sendMessage">@RazorFunction('Send')</button>
</div>

和viewmodel:

var Model = function (data) {
    var self = this;
    self.message = ko.observable(data.message)
    self.title = ko.observable(data.title)
    self.messages = ko.observableArray(data.messages);
};

其中data是具有初始值的对象。

答案 1 :(得分:0)

我只是完全忽略隐藏的输入,并将此值作为初始值提供给视图模型。

var init = {title: 'foo'};
var Model = function(initial){
    var self = this;
    self.title = ko.observable(initial.title);
    // ...
};
var vm = new Model(init);

如果真的有必要保留这个隐藏的输入,你可以尝试在viewmodel初始化发生之前获取它的值。

var init = {};
init.title = document.getElementById('title').value;
ko.applyBindings(new Model(init));