【问题标题】:Knockout subscribe to inner object of observableKnockout 订阅 observable 的内部对象
【发布时间】:2018-02-24 17:35:50
【问题描述】:

我有一个绑定 HTML 元素的 observable:

{ model: processing: { "errorMsg": "save Failed", "msgType": "info" } };

this.processing= ko.observable()

数据绑定为:

<p data-bind="text: processing().errorMsg"></p>
<p data-bind="text: processing().msgType"></p>

另一个保存用户键入的值的 observable。

self.sessionUserData=ko.observableArray();

//Computed Observable : Contains user selected UI data to save in DB.

self.UserSelectedData=ko.computed(function(){
                var obj = {
                editableMetadata : self.editableMetadata,
                sessionUserData : self.sessionUserData };
                    return obj;
                },null,
                {           
                deferEvaluation: true
                }
            ); 

我想订阅 errorMsg 以便我可以相应地更新 sessionUserData observable,如下所示。

self.processing.ErrorMsg.subscribe(function (obj) {             
                    self.sessionUserData().totalErrMsg=obj;
                }); 

以上订阅根本不起作用。 有没有办法做到这一点。

注意:还有其他类似处理的 observable,其任务只是绑定 html 元素。这个想法是用 UI 选择的数据填充 sessionUserData observable,以便它可以作为 ko 发送。 tojson(UserSelectedData) 到服务器。

【问题讨论】:

  • ErrorMsg 不是可观察的...
  • 我也试过这样但没有用。 self.processing.subscribe(function (obj) { self.sessionUserData().totalErrMsg=obj.errorMsg; });
  • 您只能订阅 observables,即使您要订阅父对象processing,那么您也只能在父对象更改时获得更新。这意味着如果更新其中的不可观察属性 (errorMsg),您将不会获得更新。哪些对象正在更新?它可能有助于为我们提供一个场景。
  • @Stanislas:我也尝试过 'self.processing.subscribe(function (obj) { self.sessionUserData().totalErrMsg=obj.errorMsg; });'但是在加载页面时执行,而不是在 '

    ' 更新为其他值时执行。

标签: knockout.js knockout-3.0


【解决方案1】:

您的问题仍然很糟糕。 我已经使用了你所有的代码块并将 JavaScript 错误更正为有效的东西。我希望这会:

  • 帮助您自行查找问题。
  • 演示如何使用如下所示的 sn-p 提出更好的问题。

注意:sn-p 中的每条评论都是我必须修复的,只是为了创建可以运行的东西。

var ViewModel = function(model) {
  this.processing = ko.observable(model.processing); //initialized this observable with the provided model, since your template is assuming that processing will always have a value.
  this.sessionUserData = ko.observableArray();

  var self = this; //Added since, you're using it inside your subcribe method.

  this.UserSelectedData = ko.computed( //This seems compleltely unnecessary for your example.
    function() {
      var obj = {
        editableMetadata: self.editableMetadata,
        sessionUserData: self.sessionUserData
      };
      return obj;
    },
    null, {
      deferEvaluation: true
    }
  ); //Removed an extra bracket here

  this.processing.subscribe(function(obj) { //Removed "ErrorMsg" since: the casing was incorrect, but also "errorMsg" is a string, not an observable, so you cannot subscribe to it.
    self.sessionUserData().totalErrMsg = obj;
  });

  this.updateProcessing = function() { //Added this method to handle the click on the "Update"-button.
    this.processing({ //Note how I'm not using the following, as that wouldn't work: this.processing().errorMsg = ...
      errorMsg: Math.random(),
      msgType: Math.random()
    }); //I used Math.random to demonstrate different values when updating.
  }
};

var model = {
  processing: {
    "errorMsg": "save Failed",
    "msgType": "info"
  }
}; //Removed "model: ", as that would be an invalid object.

var viewModel = new ViewModel(model);
ko.applyBindings(viewModel);
p {
  background-color: #ddffff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

errorMsg:
<p data-bind="text: processing().errorMsg"></p>
msgType:
<p data-bind="text: processing().msgType"></p>
<button data-bind="click: updateProcessing">Update</button>

【讨论】:

猜你喜欢
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
  • 2013-12-03
  • 2019-01-04
  • 2015-05-19
  • 2017-12-17
  • 2019-08-21
  • 2020-05-25
相关资源
最近更新 更多