Как разбить модель нокаута в деталях с requirejs

В настоящее время я работаю над приложением, которое расширяется благодаря столь большой функциональности. Здесь я собираюсь представить пример кода для понимания.

function test(){
    var self = this
    /*  Define Properties   */
    self.TaskSection = ko.observable()
    .
    .
    /*  Define Get Requrest */
    self.GetTasks = function(){

    }
    .
    .
    /*  Define Post Requrest    */
    self.PostTask  = function(){

    }
    .
    .

    /*  Define Helper Methods   */
    self.FormatDate  = function(){

    }   
    .
    .
    /*  Define Navigation Methods   */
    self.HomePage  = function(){

    }   
    .
    .
    /*  End */
}

OK. Довольно просто. Вы можете увидеть образец модели, но теперь с ней трудно работать, поскольку каждый раздел содержит много функций. Давайте рассмотрим более 10 функций в каждом разделе. Теперь я хочу управлять приложением с помощью requirejs. Это то, что я пробовал.

The Structure

app/
    js/
        /Collections/   /*  For ObservableArrays    */
        /Events/        /*  For Collections and Models  */
        /Helpers/       /*  For Collections and Models  */
        /Models/        /*  Default Properties  */

В настоящее время я хочу разбить модель на 3-4 части.

  • Collection.js, где я определяю только observableArray()
  • Events.js, где я хочу определить связанные с сервером функции
  • Helpers.js, где я хочу определить функции для выполнения внутренней работы.

Как я могу это достичь. Это то, что я пробовал.

define(["knockout"],function (ko) {
    function test(){
        var self = this
        self.TaskList = ko.observanleArray()
    }
    return new test()
});

define(["knockout","TaskList"],function (ko,TaskList) {
    var events  = function() {
        var self = this
        self.AddItem = function (data) {
            TaskList.push(TaskModel)
        }
        self.RemoveItem = function (data) {
            TaskList.remove(data)
        }
    }
    return new events()
});

define(["knockout","TaskList"],function (ko,TaskList) {
    var helpers  = function() {
        var self = this
        self.SortTaskList = function (data) {
            TaskList.sort()
        }
    }
    return new helpers()
});

Здесь я не знаю, как их объединить. TaskList в events.js и helper.js undefined. Я знаю, что мне нужно передать TaskList в качестве параметра, но я не хочу использовать функцию. Вместо этого я хочу использовать литеральный способ объединить эти два файла в ModelView.js viewmodel.

Как я могу это сделать?

Ответы

Ответ 1

Я думаю, что это пример того, что вы можете сделать (это пример, в реальной жизни вы разделились бы на отдельные файлы js):

Определите ko как модуль (не так полезный, как есть, вы можете удалить ссылку на "нокаут" )

define("knockout", function () {
    return ko;
});

Определите модуль для TaskList

define("TaskList", ["knockout"],function (ko) {
    function TaskList(){
        var self = this;
        self.NameInput = ko.observable("");
        self.DescInput = ko.observable("");
        self.TaskList = ko.observableArray();
    }
    return new TaskList();
});

Определить модуль для событий и ссылаться на TaskList

define("Events", ["knockout","TaskList"],function (ko, obj) {
    var events  = function() {
        var self = this;
        self.AddItem = function (data) {
            var inputData;
            if (typeof(data.Name) === 'undefined') {
                inputData = { Name: obj.NameInput(), 
                              Description:  obj.DescInput() };
            } else
                inputData = data;
            obj.TaskList.push(inputData);
        }
        self.RemoveItem = function (data) {
            obj.TaskList.remove(data);
        }
    }
    return new events();
});

Определите модуль для помощников, который также ссылается на TaskList

define("Helpers", ["knockout","TaskList"],function (ko, obj) {
    var helpers  = function() {
        var self = this;
        self.SortTaskList = function (data) {
            obj.TaskList.sort();
        }
    }
    return new helpers();
});

Определите основной модуль, который объединит все модули

define("Main", ["knockout","TaskList", "Events", "Helpers"], 
       function (ko, obj, e, h) {
    var main  = function() {
        var self = this;
        self.Tasks = obj;
        self.Events = e;
        self.Helpers = h;
    }
    return new main();
});

Наконец, вызовите главный модуль и попробуйте добавить элемент в список задач через модуль Events

require(["Main", "knockout"], function (main, ko) {
   main.Events.AddItem({ Name: "My first task", Description: "Start the job"});
   main.Events.AddItem({ Name:"My second task", Description:"Continue the job"});
   main.Events.AddItem({ Name: "My last task", Description: "Finish the job"});
   ko.applyBindings(main);
   console.log(main.Tasks.TaskList().length);
});

Обновлено демо

Ответ 2

Здесь стоит подумать, что require.js не просто хочет, чтобы вы создавали модули в одном файле JavaScript, он хочет, чтобы вы разбивали модули на отдельные файлы, чтобы модули не превышали размер. Проблема, с которой вы работаете, заключается в том, что у вас нет способа называть ваши модули в настоящее время, чтобы другие знали о них. Рассмотрим это -

Tasklist.js

define(["knockout"],function (ko) {
    function test() {
        var self = this;
        self.TaskList = ko.observableArray();
    };
    return new test();
});

Events.js

define(["knockout","app/TaskList"],function (ko,TaskList) {
    var events  = function() {
        var self = this;
        self.AddItem = function (data) {
            TaskList.push(TaskModel);
        };
        self.RemoveItem = function (data) {
            TaskList.remove(data);
        };
    }
    return new events();
});

Helpers.js

define(["knockout","app/TaskList"],function (ko,TaskList) {
    var helpers = function() {
        var self = this;
        self.SortTaskList = function (data) {
            TaskList.sort();
        };
    }
    return new helpers();
});

Конечно, это предполагает, что у вас уже есть main.js или какая-то точка входа с конфигурацией require.js, чтобы сообщить, где найти файлы. Если у вас нет, это будет выглядеть примерно так:

Main.js

requirejs.config({
    baseUrl: 'lib',
    paths: {
        app: '../app'
    }
});

Предполагается, что у вас есть что-то в этом направлении для вашей файловой структуры -

(проект dir)
/Приложение/
Main.js
Events.js
TaskList.js
Helpers.js

Теперь, когда вы загружаете require.js в свой html файл и указываете на main.js в качестве точки входа, все ваши модули будут загружены.