2015-09-25 58 views
1

我的數據模型由兩個對象組成;項目和任務。 我通過JSON和MVC服務加載從DB我的數據和地圖我observableArrays這樣的:如何訪問來自不同對象範圍的挖空觀測數據

viewModel = function() { 
    var self = this; 

    // some code... 

    // projects 
    self.Projects = ko.observableArray(); 
    var mappedProjects = []; 
    $.ajax({ 
     url: "myService/GetProjectsByUserId", 
     data: "userID=" + meID, 
     dataType: 'json', 
     async: false, 
     success: function (allData) { 
      mappedProjects = $.map(allData, function (item) { 
       return new Project(item); 
      }); 
     } 
    }); 
    self.Projects(mappedProjects); 

    // tasks 
    self.Tasks = ko.observableArray(); 
    var mappedTasks = []; 
    $.ajax({ 
     url: "myService/GetTasksByUserID", 
     data: "userid=" + meID, 
     dataType: 'json', 
     async: false, 
     success: function (allData) { 
      mappedTasks = $.map(allData, function (item) { 
       return new Task(item, self.Projects); // is there a smarter way to access self.Projects from the Scene prototype? 
       //return new Task(item); 
      }); 
     } 
    }); 
    self.Tasks(mappedTasks); 


    //some more code... 

}; 

其中

Project = function (data) { 
    this.projectID = data.projectID; 
    this.type = ko.observable(data.type); 
}; 


Task = function (data, projects) { 

    this.taskID = data.taskID; 
    this.projectID = data.projectID; 

    //this.projecttype = ??? simpler solution? 

    this.projecttype = ko.computed(function() { // Is there a simpler way to access 'viewModel.Projects' from within 'Task'? 
     var project = ko.utils.arrayFirst(projects, function (p) { 
      return p.projectID === self.projectID; 
     }); 
     if (!project) { 
      return null; 
     } 
     else { 
      return project.headerType(); 
     } 
    }); 

}; 

的事情是(你看),我要訪問的項目類型在Task對象內部。有沒有比使用self.Projects作爲輸入實例化對象更簡單的方法?

可以self.Projects被綁定時,以某種方式定義,所以我可以通過DOM訪問它?

+0

yes!如果你在'viewModel'函數中聲明瞭所有的函數,那麼'self.Projects'就可以在全局上用於內部函數,即Task。 –

+0

我看到的稍微大一點的問題是,你正在初始化ajax調用後的self.projects;因爲它是異步的,self.Projects永遠不會使用實際的映射數據來設置,而是空的數組 – dfperry

+0

如何從Task = function(data){}訪問viewModel? 當我訪問數據時viewModel沒有被綁定,會不會導致問題? –

回答

1

從您的意見,它看起來像你有多個視圖模型依賴於TaskProject對象。對於組件之間的解耦,我會說使用ko.postbox插件。您可以使用publishOnsubscribeTo擴展名輕鬆實現視圖模型和非基礎組件之間的同步。

所以你Task對象將認購ProjectsobservableArray在視圖模型像

Task = function (data) { 

    this.taskID = data.taskID; 
    this.projectID = data.projectID; 
    var projects = ko.observableArray().subscribeTo("projectsLoaded",true); 

    //this.projecttype = ??? simpler solution? 

    this.projecttype = ko.computed(function() { // Is there a simpler way to access 'viewModel.Projects' from within 'Task'? 
     var project = ko.utils.arrayFirst(projects(), function (p) { 
      return p.projectID === self.projectID; 
     }); 
     if (!project) { 
      return null; 
     } 
     else { 
      return project.headerType(); 
     } 
    }); 

}; 

,並在您的視圖模型,你就必須讓項目可觀測陣列發佈「projectsLoaded」主題/事件。像

viewModel = function() { 
    var self = this; 
    // some code... 
    // projects 
    self.Projects = ko.observableArray().publishOn("projectsLoaded"); 
    // .... 
} 

每當視圖模型的projects數組的變化,你將永遠在任務project陣列的最新值。

JsFiddle:http://jsfiddle.net/newuserjs/wffug341/3/

+0

非常感謝!這很有幫助使用ko.postbox @Dandy。我正在用一些「頁面」或視圖模型構建一個SPA,其中一些正在重複使用「項目」和「任務」。通常我選擇syncWith() - 選項。但是當耦合我的數據對象時(比如在Project對象上添加一個作爲observableArray的任務時),我很難與遞歸做鬥爭。真的很想看到關於如何做這個結構的教程/最佳實踐。 –

+0

你知道如果我可以使用「subscribeTo(」projectsLoaded「)」如果源數據與syncWith(「projectsLoaded」)共享嗎? –

+1

@Asle,是的,你可以訂閱。 – Dandy