2012-07-23 60 views
2

在基于Knockoutjs和Sammy.js的Web应用程序中,我有三个以父 - 子方式相互依赖的可观察对象(第二个是第一个孩子,第三个是第二个孩子) 。我的HTML有三个部分,一次只能看到一个部分。每个部分都依赖于使用可见绑定提到的其中一个观察对象。在knockoutjs中嵌套的observables

我的URL方案的布局类似于/#id-of-parent/id-of-child/id-of-grandchild(在Sammy.js中)。

如果我访问一个完整的URL(其中一个带有全部三个ID),我就会对这些观察值产生麻烦。在Sammy规则函数中,我首先加载并存储父项,然后是子项,最后是孙子(这实际上是用户想要查看的数据)。问题是父母和孩子的绑定也被触发。

有没有办法避免触发绑定或有没有更好的方法来组织这样的应用程序?

这里是我的萨米路线:

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(); 
+0

您可以发布您的Sammy代码。 – Tyrsius 2012-07-23 15:28:31

+0

已添加Sammy代码。 – fiskeben 2012-07-24 08:21:58

+0

因此,为了澄清,如果你想要设置currentStudy,currentVariableGroup和currentVariable,但你不希望任何订阅者(比如html绑定或者可观测的)从前两个更新? – Tyrsius 2012-07-24 16:03:09

回答

1

我不认为这是可能的,而且有很好的理由。它违反了数据绑定原则来更新订阅者而不通知订阅者。我强烈建议您重构您的程序,以便更新currentStudycurrentVariableGroup不会导致不必要的副作用。让其他因素决定所需的效果,可能是activeTemplate可观察。

在任何情况下,这里是the source codeobservable。请注意,内部值是私人成员,不能从外部访问。它只能通过调用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; 
     } 
    }