2

KnockoutjsとSammy.jsに基づくWebアプリには、親子の方法で相互に依存する3つのオブザーバブルがあります(2つ目は最初の子、3つ目は2番目の子です)。私のHTMLには3つのセクションがあり、一度に1つだけ表示する必要があります。各セクションは、目に見えるバインディングを使用して、言及されたオブザーバブルの1つに依存します。

私のURLスキームは、/#id-of-parent / id-of-child / id-of-grandchild(Sammy.js内)のようにレイアウトされています。

完全なURL(3つのIDすべてを持つURL)にアクセスすると、オブザーバブルで問題が発生します。サミールール関数では、最初に親、次に子、最後に孫(実際にはユーザーが表示したいデータ)をロードして保存します。問題は、親と子のバインディングもトリガーされることです。

バインディングのトリガーを回避する方法はありますか、またはこのようなアプリを整理するためのより良い方法はありますか?

これが私のサミールートです:

Sammy(function() {
  this.get('#study/:id', function() {
    self.studylist(null);
    self.currentStudy(Study.loadById(this.params.id));
  });

  this.get('#study/:id/variableGroups', function() {
    self.variableGroupList(self.currentStudy().variableGroups());
    self.currentVariable(null);
  });

  this.get('#study/:id/variable-group/:variableGroup/variables', function() {
    var groupId = this.params.variableGroup;
    $.ajax(apiUrl + "/variable-group/" + groupId, {
      type: "GET",
      async: false,
      cache: false,
      context: this,
      success: function(data) {
        if (!self.currentStudy()) {
          self.currentStudy(Study.loadById(this.params.id));
        }
        self.currentVariableGroup(new VariableGroup(data.variablegroup));
        self.variableList(self.currentVariableGroup().variables);
      }
    });
  });

  this.get('#study/:id/:variableGroupId/:variableId', function() {
    var variableId = this.params.variableId;
    $.ajax(apiUrl + "/variable/" + variableId, {
      type: "GET",
      async: false,
      cache: false,
      context: this,
      success: function(data) {
        if (!self.currentStudy()) {
          self.currentStudy(Study.loadById(this.params.id));
        }
        if (!self.currentVariableGroup()) {
          self.currentVariableGroup(VariableGroup.loadById(this.params.variableGroupId));
        }
        self.currentVariable(new Variable(data.variable));
      }
    });
  });

  this.get("", function() {
    self.currentStudy(null);
    self.currentVariableGroup(null);
    self.currentVariable(null);
    $.get(apiUrl + "/study/all", function(data) {
      var mappedStudies = $.map(data.studies, function(item, index) {
        return new Study(item);
      });
      self.studylist(mappedStudies);
    });
  });

  this.get('', function() { this.app.runRoute('get', "")});

}).run();
4

1 に答える 1

1

私はこれが可能ではないと思います、そして正当な理由があります。サブスクライバーに通知せずにサブスクライブ可能なものを更新することは、データバインディングの原則に違反します。currentStudy更新しcurrentVariableGroupて不要な副作用が発生しないように、プログラムをリファクタリングすることを強くお勧めします。他のいくつかの要因が、おそらくactiveTemplate観察可能な、望ましい効果を決定するようにします。

いずれにせよ、ここにのソースコードがありobservableます。内部値はプライベートメンバーであり、外部からアクセスできないことに注意してください。observable(サブスクライバーに通知)を呼び出すことによってのみ設定できます。

ko.observable = function (initialValue) {
    var _latestValue = initialValue; //Value is in closure, inaccessible from outside

    function observable() {
        if (arguments.length > 0) {
            // Write

            // Ignore writes if the value hasn't changed
            if ((!observable['equalityComparer']) || !observable['equalityComparer'](_latestValue, arguments[0])) {
                observable.valueWillMutate();
                _latestValue = arguments[0];
                if (DEBUG) observable._latestValue = _latestValue;
                observable.valueHasMutated();
            }
            return this; // Permits chained assignments
        }
        else {
            // Read
            ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation
            return _latestValue;
        }
    }
于 2012-07-25T15:52:37.250 に答える