我有一系列的处方受试者(a->B->C->a),但最后一步不起作用

I have a chain of Rx.Subjects (A->B->C->A), but the final step is not working

本文关键字:gt 不起作用 最后一步 受试者 一系列      更新时间:2024-03-22

实时示例。

我对Rx*完全陌生。我正在尝试为我的论文创建一个使用RxJS的MVC的反应版本。它松散地基于https://github.com/staltz/mvi-example

在开始编写代码之前,我可能应该多学习RxJS,但我意识到,我通常只需跳到池的深处就能学到最好的东西。然而,现在我完全陷入了困境。

"视图"有一个文本字段,其中包含一个数值和一个按钮。按下按钮可更改文本的颜色,单击文本可迭代数值。该值存储在模型中,因此"链"会穿过所有三个对象(视图->控制器->模型->视图)。按下该按钮不需要模型,因此链为视图->控制器->视图。

其他一切都有效,但链的最后一部分(->View)给我带来了麻烦。单击文本(在视图中)会将更改传播到控制器和模型,但视图不会收到模型更改的通知。我不明白为什么,因为我理解这一切的方式都是一样的。

我在下面的代码示例中添加了注释,以指定未被调用的函数。

此处提供代码。请注意,正如我所说,代码是为我的论文编写的,因此一些设计决策和应用程序本身可能看起来很奇怪。下面我也试着把我觉得最相关的部分包括在内。我知道我应该提供一个完整的例子,但在这种情况下这是不可能的。

对象获取的"obs"参数是一个内部数据结构,我用它来存储可观测值。相关部分为

var OBSERVABLES = {
    observe: function(source, observer, observer_name) {
      this.request(source, function(s) {
        console.log("'t[" + source + " is being observed by " + observer_name + " (" + s.constructor.name + " -> " + observer.constructor.name + ")]")
        return s.subscribe(
          function myOnNext(x) {
            console.log("'t(" + source + ") " + s.constructor.name + " -> OnNext -> (" + observer_name + ") " + observer.constructor.name)
            observer.onNext(x)
          },
          function myOnError(err) {
            console.log(error)
          })
      })
    },

View.js

var modelAmount = new Rx.Subject()
var textClicks = new Rx.Subject()
var buttonClicks = new Rx.Subject()
var changeColors = new Rx.Subject()
function View(obs, div) {
  console.log("View :: New View")
  obs = obs
  div = div
  var self = this
  obs.observe("clickAmount", modelAmount, "modelAmount")
  obs.observe("changeColor", changeColors, "changeColors")
  obs.add("textClicks", textClicks)
  obs.add("buttonClicks", buttonClicks)
  //Draw HTML elements
  render(div);
}
...
function onClick() {
  console.log("View :: onClick() emits 'textClicks'");
  textClicks.onNext()
}
function onButtonClick() {
  console.log("View :: onButtonClick() emits 'buttonClicks'");
  buttonClicks.onNext()
}
//Listen to controllers instruction to change the color
// DOES NOT WORK
var changeNumberColor = changeColors.map(function(c) {
  console.log("View :: Listened to 'changeColor'")
  if (c === undefined) {
    c = getColor()
  }
  CONTENT.css('color', c)
});
//Listen to model's instruction to change the value
// DOES NOT WORK
var setValue = modelAmount.last(function(latestValue) {
  console.log("View :: Listened to 'clickAmount'")
  console.log("View :: setValue(" + latestValue + ")")
  CONTENT.text(latestValue)
});

Controller.js

  var inputTextClicks = new Rx.Subject();
  var inputButtonClicks = new Rx.Subject();
  var obs = null;
  function Controller(obs){
    console.log("Controller :: New Controller")
    obs = obs
    obs.observe("textClicks", inputTextClicks, "inputTextClicks")
    obs.observe("buttonClicks", inputButtonClicks, "inputButtonClicks")
    obs.add("addAmount", addAmount);
    obs.add("changeColor", changeColor);
  }
  //Listen to input events and give instructions to model
  var addAmount = inputTextClicks.map(function(){
    console.log("Controller :: addAmount() listened to 'textClicks' and emits 'addAmount'")
    return 1;
  });
  //Listen to button presses and give instructions to the view
  var changeColor = inputButtonClicks.map(function(){
    console.log("Controller :: ChangeColor() listened to 'buttonClicks' and emits 'changeColor'")
    return 1;
  });

js型

  var controllerAddAmount = new Rx.Subject();
  var obs = null;
  //Stores the texts value. Starts at 0
  var VALUE = 0;
  function Model(obs){
    console.log("Model :: New Model")
    obs = obs
    obs.observe("addAmount", controllerAddAmount, "controllerAddAmount")
    obs.add("clickAmount", amountChanged)
  }
  //Listen to the controller about changing the value, notify the view about the new value
  var amountChanged = controllerAddAmount.map(function(val){
    console.log("Model :: amountChanged() listened to 'addAmount' and emits 'clickAmount'")
    VALUE += val
    console.log("Model :: Amount Changed to " + VALUE)
    return VALUE;
  })

所以问题是View.setValue()和View.setNumberColor().

您有很多基本上看起来像这样的代码:

// Listen to x to ...
var a = x.map(function (val) { ... });

但你永远不会展示你对a做了什么。map获取一个可观察到的并生成一个新的可观察到,该可观察将运行所提供的映射操作。然而,它返回的可观测值是惰性,除非您最终订阅a(或a的某些衍生物),否则实际上不会做任何事情。

看起来,对于您的控制器和模型,您最终订阅了它们正在产生的可观察性(通过将它们添加到obs,然后在视图中订阅它们的迂回路线)。

然而,目前尚不清楚您是否订阅过changeNumberColormodelAmount。根据这两种map方法中的命令式代码,我猜在这两种情况下应该使用subscribe而不是map

此外,对于modelAmount,您使用的last运算符不正确。很可能你认为last做了一些不同的事情。