如何从不同的对象作用域访问可观察对象

How to access knockout observables from different object scopes

本文关键字:对象 作用域 访问 观察      更新时间:2023-09-26

我的数据模型由两个对象组成;项目和任务。我通过json和mvc服务从数据库加载数据,并像这样映射我的observablearray:

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

事情是(如你所见)我想访问任务对象中的projectType。有比用self实例化对象更简单的方法吗?项目作为输入?

可以自我。项目被绑定时,以某种方式定义,所以我可以通过DOM访问它?

从你的评论,看起来你有多个视图模型依赖于TaskProject对象。对于组件之间的解耦,我会说使用ko。邮箱插件。您可以使用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中,你只需要让项目的可观察数组发布" projectloaded "主题/事件。像

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

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

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