如何从不同的对象范围访问knockout observable

时间:2015-09-25 12:42:35

标签: javascript knockout.js data-binding

我的数据模型由两个对象组成;项目和任务。 我通过json和MVC-services从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-object中的projectType。有没有比使用self.Projects作为输入实例化对象更简单的方法呢?

在以某种方式定义self.Projects时,我可以通过DOM访问它吗?

1 个答案:

答案 0 :(得分:1)

根据您的评论,您看起来有多个视图模型依赖于TaskProject个对象。对于组件之间的分离,我会说使用ko.postbox插件。您可以使用publishOnsubscribeTo扩展轻松地在视图模型和非敲除组件之间实现同步。

因此,您的Task对象将在viewModel中订阅Projects observableArray,如

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();
        }
    });

};

并且在您的viewModel中,您只需要使Projects observable数组发布“projectsLoaded”主题/事件。喜欢

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

每当projects数组在viewModel中发生更改时,您将始终拥有Task project数组中的最新值。

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