【问题标题】:knockoutjs data bind hidden field valueknockoutjs 数据绑定隐藏字段值
【发布时间】:2015-05-29 20:36:46
【问题描述】:

我在敲除模板中有一个隐藏字段,它的值使用 jquery 更新。问题是当尝试使用 ajax 将此值传递给服务器时,我在控制器中得到空值。但是html源码显示隐藏字段的值是更新的。如果我将隐藏字段替换为文本框,则只有在我手动输入文本时才能正常工作。

jQuery

        function getFileDetail(fileID, fileName) {
        $('#hdnFileName' + fileID).val(fileName);
        $('#lblFileName' + fileID).text(fileName);
    }

这里是 html 敲除模板:

    <script type="text/html" id="fileTemplate">
        <div data-role="fieldcontain">
            <a href="#" data-bind="click: function () { openFileUpload('file', ID) }"><label data-bind="text: 'File Upload ' + ID, attr: { id: 'lblFileName' + ID }"></label></a><input type="button" value="Remove" data-bind="click: removeFile" /> 
        </div>
        <input type="hidden" name="hdnFileName" data-bind="attr: { id: 'hdnFileName' + ID, value: fileName }" />
    </script>

视图模型

function FileViewModel() {
        var self = this;
        self.ID = ko.observable();
        self.fileName = ko.observable();
        self.removeFile = function (file) { };
        self.Files = ko.observableArray([{ ID: 1, fileName: "", removeFile: function (file) { self.Files.remove(file); }}]);

        self.addNewFile = function () {
            var newFile = new FileViewModel();
            newFile.ID = self.Files().length + 1;
            newFile.fileName = "";
            newFile.removeFile = function (file) { self.Files.remove(file); };
            self.Files.push(newFile);
            //$("input[name='hdnFileName'").trigger("change");
        }
    }
function ViewModel() {
        var self = this;
        self.fileViewModel = new FileViewModel();
        self.submitForm = function () {

            $.ajax({
                type: "POST",
                url: "<%= Url.Action("MeetingPresenter")%>",
                data: "{Files:" + ko.utils.stringifyJson(self.fileViewModel.Files) + "}",
                contentType: "application/json",
                success: function (data) {},
            });
        };
    }

【问题讨论】:

  • 在哪里插入带有jQuery的值?
  • 您使用 attr 绑定来绑定值似乎很奇怪。您不使用值绑定是否有原因?
  • @adricadar 我刚刚添加了 jQuery

标签: ajax knockout.js data-binding hidden-field


【解决方案1】:

您的模型属性ID 是可观察的,因此在连接时需要“解包”以从中获取值,如下所示:

<input type="hidden" name="hdnFileName" data-bind="attr: { id: 'hdnFileName' + ID(), value: fileName }" />

还有这个:

<label data-bind="text: 'File Upload ' + ID(), attr: { id: 'lblFileName' + ID() }"></label>

【讨论】:

  • 谢谢大卫。但我试过这个,它给出了一个错误 ID() is not a function。
【解决方案2】:

如果您使用knockout.js,则无需修改DOM,您只需更新ViewModel,DOM将根据更新

function getFileDetail(fileID, fileName) {
    viewModel.fileViewModel.update(fileID, fileName);
}

FileViewModel中添加update函数

function FileViewModel() {
    // rest of the code

    self.update = function(fileID, fileName) {
        var file = ko.utils.arrayFirst(self.Files(), function(file) {
            return file.ID == fileID;
        });

        file.fileName(fileName); // this will change and the UI will be updated according
    };
}

注意:请注意您在Files 中有一个默认项,它不会被update 函数更改,因为属性不是observable

self.Files = ko.observableArray([{ ID: 1, fileName: "", removeFile: function (file) { self.Files.remove(file); }}]);

您可以通过将它们设为observable(即ID: observable(1))来解决此问题,或者您可以创建一个new FileViewModel()

注意:viewModel必须在函数中可以访问(即全局实例),否则为undefined

【讨论】:

  • 我已将更新功能添加到 FileViewModel,但由于某种原因,文件的值为 null。我错过了什么吗?
  • @WS84 这个想法是找到匹配条件的元素。您可以找到其他方法来查找与该条件匹配的元素。您也可以设置刹车点以确保 fileID 包含您想要的内容并且数组具有该元素。
  • 现在运行完美!我只需要创建 ViewModel() 的全局实例。谢谢!
【解决方案3】:

在我看来,通过 DOM 设置字段的值不会与敲除交互。如果您使用.value 设置其值,则不会更新可观察对象。你应该更新 observable。

我写了一个小小提琴来演示。每 2 秒,它会通过 DOM 设置输入的值,但绑定的 observable 仅在您键入内容时才会更改。

http://jsfiddle.net/qcv01h2e/

var viewModel = (function () {
    return {
        fv: ko.observable().extend({notify:'always'})
    };
}());

ko.applyBindings(viewModel);
setInterval(function () {
    console.debug("Set it");
    var f = document.getElementById('field');
    f.value = "Hi";
    console.debug("fv is", viewModel.fv());
}, 2000);

【讨论】:

    【解决方案4】:

    我遇到了一个类似的问题,我需要在没有用户输入的情况下设置一个值。 在执行点击更新功能之前,我会进行所需的模型更新。如果你有模式操作最好在模型中引入一个函数。

    <input data-bind="click: function(){ isEnabled(true); update() }" />
    

    我实际上做的是,

    <input data-bind="click: function(){ isEnabled(!isEnabled()); update() }" />
    

    请记住 javascript 的异步特性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      • 2011-08-29
      • 1970-01-01
      • 2013-12-22
      • 2012-08-14
      相关资源
      最近更新 更多