简体   繁体   English

当绑定控件(也是动态创建的)更改时,动态创建的 Knockout observable 不会更改值

[英]Dynamically created Knockout observable does not change value when a bound control (also dynamically created) is changed

I'm working on an MVC Web application with ASP.NET and Knockout js (V3.5.1).我正在使用 ASP.NET 和 Knockout js (V3.5.1) 开发 MVC Web 应用程序。 I'm struggling with Knockout observable not updated when an input value is change.当输入值更改时,我正在努力解决 Knockout observable 未更新的问题。 Both of them are dynamically created in Javascript.它们都是在 Javascript 中动态创建的。 The initial value set to the observable is not reflected on the input when the observable is created.创建可观察对象时,设置为可观察对象的初始值不会反映在输入上。 I'm puzzled why the observable not catching the input's change.我很困惑为什么 observable 没有捕捉到输入的变化。

Please find my code below for further demonstration.请在下面找到我的代码以进行进一步演示。 I really appreciate if there is any help.如果有任何帮助,我真的很感激。

CustomViewModel.cs自定义视图模型.cs

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

HTML with Razor HTML 与 Razor

@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>
}

/Scripts/ViewModels/CustomFormViewModel.js code /Scripts/ViewModels/CustomFormViewModel.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);
};

I will only focus on the issue at hand- which is the input.我将只关注手头的问题——即输入。

In general, since you are using knockoutJS you should refrain from using jQuery to append elements to the dom, instead you should change your View, so that it reflects what you are trying to achieve.一般来说,由于您使用的是 knockoutJS,因此您应该避免使用 jQuery 到 append 元素到 dom,而是应该更改您的视图,以便它反映您想要实现的目标。

So you should have something like so:所以你应该有这样的东西:

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

This way you control if the input should be rendered/shown, instead of appending it later on via jQuery.这样您就可以控制是否应该渲染/显示输入,而不是稍后通过 jQuery 附加它。

When you call applyBindings you only bound to any html already existing on the view.当您调用 applyBindings 时,您只绑定到视图上已经存在的任何 html。 Because you are injecting the input AFTER you have already bound the vm to the view, the engine does not know of the element since its not controlled by knockout, but rather added by you manually.因为您在将 vm 绑定到视图之后注入输入,所以引擎不知道该元素,因为它不受淘汰赛控制,而是由您手动添加。

One way to solve this would be to actually call the razor inside the normally rendered view, so that when the applyBindings is executed, the input element exists on the dom解决这个问题的一种方法是在正常渲染的视图中实际调用 razor ,以便在执行 applyBindings 时,输入元素存在于 dom

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

The only other option would be to clearBindings on the element and-rebind, which is also a bad practice for this use-case.唯一的其他选择是清除元素上的绑定并重新绑定,这对于这个用例来说也是一个不好的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM