-1

実例。

私は Rx* はまったく初めてです。論文に RxJS を使用して MVC のリアクティブ バージョンを作成しようとしています。大まかにhttps://github.com/staltz/mvi-exampleに基づいています

コーディングを始める前に RxJS をもっと勉強しておくべきだったのかもしれませんが、私は通常、プールの深いところにジャンプするだけで最善のことを学べることに気付きました。しかし、今は完全に立ち往生しています。

ビューには、数値とボタンを含むテキスト フィールドがあります。ボタンを押すとテキストの色が変わり、テキストをクリックすると数値が繰り返されます。値はモデルに保存されるため、「チェーン」は 3 つのオブジェクト (View->Controller->Model->View) をすべて通過します。ボタンを押すのにモデルは必要ないので、チェーンは View->Controller->View です。

他のすべては機能しますが、チェーンの最後の部分 (->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;
  });

Model.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() です。

4

1 に答える 1

1

基本的に次のようなコードがたくさんあります。

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

しかし、その後、あなたが何をしているのかを示すことは決してありませんa. mapオブザーバブルを受け取り、提供されたマッピング操作を実行する新しいオブザーバブルを生成します。ただし、それが返すオブザーバブルは不活性aであり、最終的にサブスクライブしない限り(またはその派生物) 、実際には何もしませんa

コントローラーとモデルの場合、それらが生成しているオブザーバブルを最終的にサブスクライブするように見えます (それらをあなたに追加してからobs、ビューでそれらをサブスクライブするという遠回りのルートを通じて)。

changeNumberColorただし、またはに登録したことがあるかどうかは明らかではありませんmodelAmount。これら 2 つのメソッド内の命令コードに基づいて、これら 2 つのケースの代わりにmap使用する必要があると思います。subscribemap

また、演算子modelAmountの使い方がlast間違っています。lastほとんどの場合、それとは異なることをしていると思います。

于 2015-02-24T13:41:36.450 に答える