javascript - 在knockout js中applybind之后添加新属性到 View 模型

标签 javascript model-view-controller knockout.js viewmodel knockout-mapping-plugin

我不太擅长 knockout js,所以我可能错过了一些东西。

我的用例:

我有一个简单的 View 模型。我的页面如下所示

     <body>
    <hr />
    <div>
      <label for="">
            Basic :</label>
      <input type="text" name="" data-bind="value: basic" id="txtBasic" />
    </div>
    <div>
      <label for="">
            HRA :</label>
      <input type="text" name="" data-bind="value: hra" id="txtHra" />
    </div>
    <div>
      <div style="background-color:silver;">
        <hr />
        <label for="">
          <input type="button" data-bind="click : generateModelValue" value="Generate Runtime Property" />
          <input type="button" data-bind="click : tryRebind" value="Try Rebinding with clean node" />
<br>
                DA :</label>
         <input type="text" name="" id="txtDa" data-bind="value: $data.da"><br><br></div>

      </div> 
      <hr />
      <div>
        <label for="">
                Tax :</label>
        <input type="range" name="" id="rangeTax" min="0" max="30" value="0" data-bind="value: tax" />
        <span id="spanTax">[Tax%]</span>
      </div>
      <div>
        <input type="button" value="Calculate" id="btnCalculate" data-bind="click: computeSalary" />
      </div>
      <div>
        <div id="divResult" data-bind="text: salary">
                [Salary]</div>
      </div>
    </div>
    <script>

            myViewModel={
                basic: ko.observable(1000),
                hra: ko.observable(10),

                tax: ko.observable(10),
                salary: ko.observable('Yet to be calculated'),
                computeSalary: function () {
                    this.salary(this.basic()+this.da()+this.hra());
                },
                generateModelValue: function () {
                  debugger;
                    this.da=ko.observable("123");
                },
                tryRebind: function () {
                  debugger;
                  alert("Why do i have to call this to update the view model");
                    ko.cleanNode($('body')[0]);
                    ko.applyBindings(myViewModel,$('body')[0]);
                }
            };

            ko.applyBindings(myViewModel,$('body')[0]);


        </script>
  </body>

我想在运行时添加一个属性(在本例中为“da”)。因此,为了使示例易于阅读,我将在模型上调用“generateModelValue”函数,该函数将添加“myViewModel”上的“da”属性,示例值为“123”。

这成功创建了一个新的可观察属性(我用console.log检查过)。 但不更新 UI

因此,在单击之后,我在 View 模型上调用了另一个函数,该函数将尝试执行 ko.cleanNode($('body')[0]) ,然后执行 ko .applyBindings(myViewModel,$('body')[0]); 然后更新 UI。


我的问题:

我是否必须调用干净节点,或者是否有更好的方法可以在 View 模型更新后立即更新 UI?

我的疑问:

  1. 我不认为使用干净节点是实现这一目标的好方法?
  2. 如果对象过于复杂或尺寸太大,是否会导致任何性能问题。
  3. 我正在使用 "<input type="text" name="" id="txtDa" data-bind="value: $data.da">" 在我的 HTML 中(以便当我使用 viewModel 中不可用的属性调用 applyBinding 时不会引发未定义的错误)
    是否真的需要$data(还有其他选择吗?)

访问的帖子: Adding properties to the view model created by using the Knockout JS mapping plugin
(我不太确定我理解这篇文章。如果推荐,我会再看一遍,因为我也使用映射插件将 AJAX 调用的纯 json 响应转换为可观察 View 模型,但我的实现有点不同)

现场骗子: http://plnkr.co/edit/4EwSdKihVak1dGhuobbi?p=preview


已编辑:
为什么我需要实现这一目标 -

因为当我调用 ko.applybinding 时,我的 viewModel 将始终小于 HTML 标记中所需的数据绑定(bind)属性,因此会抛出未定义的错误(我使用了 $data以避免此错误)。

因此,在 ko.applyBinding(html-element) 内部传递的最终 html View 将是构成屏幕的几个较小 html 片段的 UNION。

并且在调用应用绑定(bind)时不可能收集所有 View 模型属性,因为 View 模型的复杂性会随着用户交互(Ajax 调用)而增加

我希望它很清楚。如果没有,我正在为此创建一个 plunkr。很快就会更新。

已更新
新笨蛋 http://plnkr.co/edit/8PNHk25jl2xig0GLyqQq?p=preview

在上面的 plunkr 部分中包含

<div data-bind="visible: $data.da">
         You will see this section only if the da property is available on the view model
         </div>

在 applybind 时将存在于 DOM 中,但“da”的值不会。 在一些用户交互之后, View 模型将被更新,因为对象将通过 ajax 调用接收新属性(例如上面 plunkr 中的 da)。因此将显示 da 部分。

最佳答案

我认为你误解了 knockout 的运作方式。在某些情况下,例如动态列表等,并非所有可观察量都会立即可用。然而,您的可观察到的只是模型的一个属性。此可观察量应与 basichra 一起创建。延迟其创建没有任何好处。

将代码更改为:

myViewModel = {
    basic: ko.observable(1000),
    hra: ko.observable(10),
    da: ko.observable(null),

如果您想表示在函数 generateModeValue 之前尚未设置该值,则让 null 表示这一点或创建该函数可以设置的另一个 bool 可观察量。例如:

myViewModel = {
    basic: ko.observable(1000),
    hra: ko.observable(10),
    da: ko.observable(null),
    daIsSet: ko.observable(false),
    ...
    generateModelValue: function () {
        debugger;
        this.da("123");
        this.daIsSet(true);
    },
    ...

同样,可以动态添加可观察量(使用数组或其他一些方法),但这种情况不需要这种功能。希望这能为您澄清一些概念。

关于javascript - 在knockout js中applybind之后添加新属性到 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28345940/

相关文章:

php - 添加到 Controller 的内容和添加到模型的内容

javascript - 如何可靠地确定浏览器是否支持鼠标悬停事件?

javascript - 将多个系列加载到图表中

javascript - 没有包装器的 iframe 维基百科文章

javascript - 在 Knockout JS 中处理多维数组的最佳方法是什么?

data-binding - Knockout.js 基于 css 类添加可见性 observable

javascript - Knockout.js:组合 javascript 对象并选择选项

javascript - 比较 2 个数组并检查位置

php - 关注点分离; MVC;为什么?

java - 我可以将 servlet 与 Angular JS 结合使用并实现 MVC 架构吗?