knockout.js 当绑定控件(也是动态创建的)发生更改时,动态创建的Knockout可观察对象不会更改值

bvjveswy  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(141)

我正在使用ASP.NET和Knockout js(V3.5.1)开发一个MVC Web应用程序。我正在努力解决Knockout可观察值在输入值改变时不更新的问题。它们都是在Javascript中动态创建的。当可观察值创建时,设置为可观察值的初始值没有反映在输入上。我很困惑为什么可观察值没有捕捉到输入的变化。
请在下面找到我的代码,以便进一步演示。如果有任何帮助,我真的很感激。

自定义视图模型.cs

public class CustomViewModel
    {
         public int Id { get; set; }
         public int Prop { get; set; }
    }

带Razor的HTML

@model CustomViewModel

<div id="inputContainer"></div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval", "/Scripts/ViewModels/CustomFormViewModel.js")
    <script>
        var vm = new CustomFormViewModel(@HtmlHelperExtensions.HtmlConvertToJson(Html, Model));

        vm.createInput = function (data) {
            return `@Html.Editor("Prop", new { @htmlAttributes = new { @id = "${data.Id}Prop", @data_bind = "value: ${data.Id}Prop" } })`;
        };
        ko.applyBindings(vm);
    </script>
}

/脚本/视图模型/自定义表单视图模型.js代码

function CustomFormViewModel(self) {
      var self = this;

      var data = loadData();
      self[`${data.Id}Prop`] = ko.observable(data.Prop);

      var newInput = self.createInput(data);
      $("#inputContainer").append(newInput);
};
gpfsuwkq

gpfsuwkq1#

我将只关注手头的问题--即输入。
一般来说,由于您使用的是knockoutJS,因此您应该避免使用jQuery将元素追加到dom中,而应该更改View,以便它反映您试图实现的目标。
所以你应该有这样的东西:

<div data-bind="if: showThisInput">
    <input data-bind="value: myBindedObservable"
</div>

通过这种方式,您可以控制是否应该呈现/显示输入,而不是稍后通过jQuery追加它。
当你调用applyBindings时,你只绑定到视图上已经存在的任何html。因为你是在你已经将vm绑定到视图之后注入输入的,引擎不知道元素,因为它不是由knockout控制的,而是由你手动添加的。
解决此问题的一种方法是在正常呈现的视图中实际调用剃刀,以便在执行applyBindings时,input元素存在于dom上

@Html.Editor("Prop", new { @htmlAttributes = new { @id = "${data.Id}Prop", @data_bind = "value: ${data.Id}Prop" } })

唯一的其他选择是清除元素上的Bindings并重新绑定,这对于此用例也是一个不好的做法。

相关问题