2015-09-25 2 views
1

Моя модель данных состоит из двух объектов; проекта и задачи. загружаю мои данные из БД с помощью JSON и MVC-сервисов и карта мои 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(); 
     } 
    }); 

}; 

Дело в том (как вы видите) Я хочу, чтобы получить доступ к projectType внутри объекта Task. Есть ли более простой способ сделать это, чем создать экземпляр объекта с помощью self.Projects как вход?

Может ли self.Projects быть связанным, если он определен каким-то образом, чтобы я мог получить к нему доступ через DOM?

+0

Да! вы можете, если у вас есть все ваши функции, объявленные в функции 'viewModel', тогда' self.Projects' становится глобально доступным для внутренних функций i.e 'Task'. –

+0

несколько большая проблема, я вижу, что вы инициализируете self.projects сразу после вызова ajax; так как это async, self.Projects никогда не будет задан с фактическими сопоставленными данными, а пустой массив – dfperry

+0

Как мне получить доступ к viewModel из Task = function (data) {}? ViewModel не связан, когда я обращаюсь к данным, это не вызовет проблем? –

ответ

1

Из ваших комментариев, похоже, что у вас есть несколько моделей в зависимости от Task и Project объектов. Для развязки между компонентами, я бы сказал, чтобы использовать плагин ko.postbox. Вы можете легко синхронизировать между режимами просмотра и не-нокаутными компонентами, используя расширения publishOn и subscribeTo.

Так что ваш Task объект подписаться на ProjectsobservableArray в ViewModel как

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, вы просто должны сделать проекты наблюдаемым массив публиковать «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/

+0

Большое спасибо! Это было полезно, используя ko.postbox, @Dandy. Я создаю SPA с несколькими «страницами» og viewmodels, а некоторые из них повторно используют «Проекты» и «Задачи». Часто я выбираю параметр syncWith() -. Но я борюсь с рекурсией при связывании моих объектов данных (как при добавлении задач как наблюдаемого массива на объект проекта). Хотелось бы увидеть учебник/лучшую практику, как это сделать. –

+0

вы бы знали, могу ли я использовать «subscribeTo (« projectsLoaded »)», если исходные данные разделяются с помощью syncWith («projectsLoaded»)? –

+1

@ Асло, да, вы можете подписаться на это. – Dandy

Смежные вопросы