2016-11-21 11 views
0

Отказ от ответственности: Апология для длинного поста, как я хочу вкратце описать свою проблему.Как централизовать регистрацию компонентов нокаута?

Я создал базовый компонент нокаута, и он был полностью работоспособен, но я пришел к выводу, что каждый раз, когда я хочу использовать свой компонент в другом шаблоне, я должен потребовать его для его потребителя/viewmodel до его работы (иначе это будет жаловаться, что мой компонент неизвестен), что заставляет меня думать, что он нарушает принцип DRY. Вместо этого я хочу, чтобы это было частью нокаута.

Сценарий: регистрация MyComponent

/*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, и не реализовал ни один из примеров в ссылке, которые создают экземпляр своей модели представления вручную через 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, который я не могу решить.

Может ли кто-то проливать мне небольшие огни или это возможно? Как я мог устранить повторение требования к моему компоненту время от времени его потребителю, но вместо этого я хочу, чтобы это было частью моего нокаута. Я хочу централизовать регистрацию в одном файле, не требуя его для своего потребителя. На данный момент это довольно боль.

ответ

0

У меня есть ключ в этом 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' } 
     }); 
    }); 
});