【问题标题】:How to Break knockout view model in parts with requirejs如何使用 requirejs 部分打破淘汰赛视图模型
【发布时间】:2014-08-08 12:08:00
【问题描述】:

我目前正在开发一个应用程序,该应用程序由于功能太多而正在自我扩展。在这里我将提供一些示例代码以供理解。

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 */
}

好的。很简单。您可以看到示例模型,但现在很难使用它,因为每个部分都包含许多功能。让我们假设每个部分中有超过 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()
});

这里我不知道如何合并它们。 events.js 和 helper.js 中的 TaskList 未定义。我知道我需要将 TaskList 作为参数传递,但我不想使用函数方式。相反,我想使用文字方式将这两个文件合并到 Tasklist.js 视图模型中。

我该怎么做?

【问题讨论】:

  • 下一个版本的淘汰赛 3.2 将对此有所帮助。值得一看:blog.stevensanderson.com/2014/06/11/…
  • 我知道这不是您明确要求的,但是您是否考虑过使用继承?例如,您可以有一个基本视图模型来定义常见的内部函数或事件,然后让您的主视图模型从它继承?
  • 感谢您的回复。为此,我已经写了两篇博客文章herehere,但问题是当视图模型变得冗长时,我想使用我上面要求的技术来管理它。

标签: knockout.js requirejs structure


【解决方案1】:

我认为这是你可以做的一个例子(这是一个例子,在现实生活中你会拆分成单独的 js 文件):

将 ko 定义为一个模块(虽然没那么有用,你可以删除对“knockout”的引用)

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

为任务列表定义一个模块

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

为事件定义一个模块并引用任务列表

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

为同样引用任务列表的 Helpers 定义一个模块

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模块将Item添加到TaskList中

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

Updated Demo

【讨论】:

  • 我已经检查了这个例子,但它不起作用。依赖项甚至没有加载
  • @raheelshan 检查你的控制台,你应该看到“1”,不是吗?
  • @raheelshan 我更新了代码和小提琴以获得更好的示例
【解决方案2】:

这里要考虑的一件事是,require.js 不仅希望您在单个 JavaScript 文件中创建模块,它还希望您将模块分解为单独的 文件 以保留模块从变得超大。您遇到的问题是您目前没有任何方法来命名您的模块,以便其他人知道它们。考虑一下 -

任务列表.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 配置的入口点,以便让 require 知道 在哪里 可以找到文件。如果你没有它,它看起来像这样 -

Main.js

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

假设您的文件结构与此类似 -

(项目目录)
/应用程序/
Main.js
事件.js
任务列表.js
Helpers.js

现在,当您在 html 文件中加载 require.js 并指向 main.js 作为入口点时,您的所有模块都将被加载。

【讨论】:

  • 我已经尝试过您在此处介绍的内容。问题是Events.jsTaskListundefined。我认为那是因为Event.js 需要TaskList 作为参数。
  • 另一件事是我使用Tasklist.js 的地方缺少事件和帮助程序,因为Tasklist.js 不依赖于它们两者
  • 我将更新定义语句以包含 app/ 参数,但我知道此方法在我现在使用时有效
  • 当然我会尽力让你知道
  • 您的任何模块都不需要助手,因此它永远不会被加载。正如您所展示的,Tasklist 基本上是一个包含模型的独立模块。如果您想从任务列表和任务列表中请求事件,那么您需要切换到使用父模块来请求这两个或使用双向方法,即 require() 另一个 之后它被加载,如 require.js 文档中所述,因为两者都不会完全加载,直到另一个是递归情况。
猜你喜欢
  • 2019-11-14
  • 2012-11-09
  • 1970-01-01
  • 1970-01-01
  • 2011-12-21
  • 2013-03-29
  • 2015-06-21
  • 2013-08-05
  • 1970-01-01
相关资源
最近更新 更多