如何集中敲除组件注册?

How to centralize knockout component registration?

免责声明: 为冗长道歉post 因为我想简要描述我的问题。

我已经创建了基本的剔除组件,它完全可以正常工作,但我发现每次我想将我的组件用于其他模板时,我都需要在它工作之前要求它达到 consumer/viewmodel(否则它会抱怨 mycomponent is unknow) 这让我觉得它违反了 DRY 原则。相反,我希望它成为淘汰赛的一部分。

场景:我的组件注册

/*mycomponent registration */

define(
[
    "knockout",
    "text!components/my-component-template.htm",
    "components/my-component-view-model"
],
function (ko, myComponentTemplate, MyComponentViewModel)
{
    "use strict";

    ko.components.register("mycomponent",
    {
        viewModel:
        {
            createViewModel: function (params)
            {
                return new MyComponentViewModel(params);
            }
        },

        template: myComponentTemplate
    });
});

我通过像往常一样要求它来使用它:

示例 1:

/* template of other consumer */

<ul data-bind='normal knockout function'>
   <li>
     <a href='#sample-only'></a>
     <!-- ko component: { name: "mycomponent", params: { data : $data } } -->
     <!-- /ko -->   
   </li>
</ul>

/* other view model 1*/

define(
[      
    "knockout",
    "mycomponent" --> I want to eliminate this and make it part of knockout
],
function ()
{
    "use strict";
    /* Normal coding stuff here */
});

示例 2:为了示例目的,假设这是不同的

/* other template that want to use mycomponent */
<ul data-bind='other template'>
   <li>
     <a href='#sample-only'></a>
     <!-- ko component: { name: "mycomponent", params: { data : $data } } -->
     <!-- /ko -->   
   </li>
</ul>

/* other view model 2 */

define(
[        
    "knockout",
    "mycomponent" --> I want to eliminate this and make it part of knockout
],
function ()
{
    "use strict";
    /* Normal coding stuff here */
});

我尝试通过了解 custom loader 的工作原理并实现 link 中的示例 none 来进行实验,这些示例通过 createViewModel 手动实例化他们的视图模型,就像我的一样上面的例子。然后,另一种我认为更简单的方法是创建 knockout-extension.js 使用它来注册我的组件和其他敲除文件,如客户绑定处理程序等,并在我的 index.cshtml 中需要它,如下所示:

/* knockout-extension.js */
define(
[        
    "<path>/mycomponent" --> Found in Scenario mycomponent registration above
], 
function()
{
      /* do nothing*/
})


/* Index */

<script type="text/javascript">

 require({
            baseUrl: '@Url.Content("~/Content/js")',
            waitSeconds: 45,
            paths:
            {
                /* 
                . other dependencies here                               
                */
                "knockout" : "<path>/knockback-extensions"
            }
}); 

但是这种方法会导致加载超时问题,就像这个 link 我无法解决。

有人可以帮我开灯吗?或者这有可能吗?我怎么能消除重复要求我的组件时不时地向它的消费者,而是我希望它成为我淘汰赛的一部分。我想将注册集中在一个文件中,而不需要它的消费者。现在还挺痛苦的。

我在这个 link 中得到了一条线索,您可以在其中要求内部定义函数。这解决了我在视图模型上的问题。

define(
[
    "knockout"
    "require"        
],
function (ko, require)
{
    "use strict";

    require(
    [
       "components/my-component-view-model"
    ],
    function (MyComponentViewModel)
    {
        ko.components.register("mycomponent",
        {
            viewModel:
            {
                createViewModel: function (params)
                {
                    return new MyComponentViewModel(params);
                }
            },

            template: { require : 'text!template-path-here' }
        });
    });
});