2016-04-01 43 views
1

我有一個模型被多個視圖模型使用,並且我需要一些其他javascript組件來更新模型,我的虛擬現實的觀察。我不知道該怎麼做,因爲在教程中,他們在視圖模型中「混合」模型。KnockoutJS:從模型視圖中分離模型

這裏是我的代碼:

var ConversationModel = { 
    conversations: ko.observableArray(), 
    open: function(userId){ 
     for(var i = 0; i < this.conversations.length; i++){ 
      if(this.conversations[i].userId == userId){ 
       return; 
      } 
     } 

     var self = this; 
     var obj = ko.observable({ 
      userId: userId 
     }); 

     self.conversations.push(obj); 

     UserManager.getUserData(userId, function(user){ 
      $.getJSON(Routes.messenger.getConversation, "receiver=" + userId, function(data){ 
       obj.receiver = user; 
       obj.data = data; 
      }); 
     }); 
    } 
}; 

function ConversationDialogViewModel() { 
    var self = this; 

    this.conversations = ko.computed(function(){ 
     return ConversationModel.conversations; 
    }); 

    console.log(this.conversations()); 

    this.conversations.subscribe(function(context){ 
     console.log(context); 
    }); 
} 
+3

你可以使用'ko.postbox'來嘗試一個發佈/訂閱模式:https://github.com/rniemeyer/knockout-postbox – cl3m

+0

你的多個viewmodel讓我覺得組件是個好主意。 http://knockoutjs.com/documentation/component-overview.html –

回答

0

你可以找到一個(合理的)很好的例子here如何結合:

  1. 組件
  2. 每頁視圖模型
  3. 中央ServiceProviders(用於例如,調用API或在不同組件之間提供狀態信息)

請注意代碼是ES2015(新的Javascript),但是如果你願意,你也可以使用純JavaScript代碼。 gulp腳本包括對組件中的任何html模板進行字符串化,以便將它們組合並作爲一個文件加載,但作爲單獨的元素進行編輯。

一個例子組件:

const ko = require('knockout') 
    , CentralData = require('../../service-providers/central-data') 
    , CentralState = require('../../service-providers/central-state') 
    , template = require('./template.html'); 

const viewModel = function (data) { 

    //Make service providers accessible to data-bind and templates 
    this.CentralData = CentralData; 
    this.CentralState = CentralState; 

    this.componentName = 'Component One'; 
    this.foo = ko.observable(`${this.componentName} Foo`); 
    this.bar = ko.observableArray(this.componentName.split(' ')); 
    this.barValue = ko.observable(""); 
    this.bar.push('bar'); 
    this.addToBar = (stuffForBar) => { 
     if(this.barValue().length >= 1) { 
      this.bar.push(this.barValue()); 
      CentralData.pushMoreData({firstName: this.componentName,secondName:this.barValue()}); 
     } 
    }; 
    this.CentralState.signIn(this.componentName); 
    if (CentralData.dataWeRetrieved().length < 10) { 
     var dataToPush = {firstName : this.componentName, secondName : 'Foo-Bar'}; 
     CentralData.pushMoreData(dataToPush); 
    } 
}; 
console.info('Component One Running'); 
module.exports = { 
    name: 'component-one', 
    viewModel: viewModel, 
    template: template 
}; 

和組件模板:

<div> 
    <h1 data-bind="text: componentName"></h1> 
    <p>Foo is currently: <span data-bind="text: foo"></span></p> 
    <p>Bar is an array. It's values currently are:</p> 
    <ul data-bind="foreach: bar"> 
     <li data-bind="text: $data"></li> 
    </ul> 
    <form data-bind="submit: addToBar"> 
     <input type="text" 
       name="bar" 
       placeholder="Be witty!" 
       data-bind="attr: {id : componentName}, value : barValue" /> 
     <button type="submit">Add A Bar</button> 
    </form> 
    <h2>Central State</h2> 
    <p>The following components are currently signed in to Central State Service Provider</p> 
    <ul data-bind="foreach: CentralState.signedInComponents()"> 
     <li data-bind="text: $data"></li> 
    </ul> 
    <h2>Central Data</h2> 
    <p>The following information is available from Central Data Service Provider</p> 
    <table class="table table-bordered table-responsive table-hover"> 
     <tr> 
      <th>Component Name</th><th>Second Value</th> 
     </tr> 
     <!-- ko foreach: CentralData.dataWeRetrieved --> 
     <tr> 
      <td data-bind="text: firstName"></td><td data-bind="text: secondName"></td> 
     </tr> 
     <!-- /ko --> 
    </table> 
    <h3>End of Component One!</h3> 
</div> 

你的目的,你可以忽略Central狀態提供商和僞API,但是,你可能會發現模型作爲有用的應用程序變得更復雜。