Reputation: 588
My data model is consisting of two objects; project and task. I load my data from the db via json and MVC-services and map my observableArrays like this:
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...
};
where
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();
}
});
};
The thing is (as you see) I want to access the projectType inside the Task-object. Is there a simpler way to do this than instantiating the object with the self.Projects as input?
Could self.Projects be bound when defined in some way so I could access it via the DOM?
Upvotes: 1
Views: 131
Reputation: 2177
From your comments, it looks like that you have multiple view models dependent on Task
and Project
objects. For decoupling between components, i would say to use ko.postbox plugin. You can easily have synchronization between viewmodels and non-knockout components using publishOn
and subscribeTo
extensions.
So your Task
object will subscribe to Projects
observableArray
in viewModel like
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();
}
});
};
and in your viewModel, you just have to make Projects observable array publish "projectsLoaded" topic/event. Like
viewModel = function () {
var self = this;
// some code...
// projects
self.Projects = ko.observableArray().publishOn("projectsLoaded");
// ....
}
Whenever the projects
array changes in viewModel, you will always have the latest value in Task project
array.
JsFiddle: http://jsfiddle.net/newuserjs/wffug341/3/
Upvotes: 1