2016-08-05 8 views
0

Новое для нокаута Я пытаюсь создать POC для пользовательских элементов.Пользовательский элемент внутри foreach не ожидал модель в нокауте

Модели просты, MainModel содержит массив LinkModel.

Цель состоит в том, чтобы перебирать массив ссылок для отображения 1 настраиваемого элемента «settings-view-link» для каждого объекта LinkModel.

function LinkModel(params) { 
    var self = this; 
    self.name = ko.observable(params.name); 
} 

function MainModel() { 
    var self = this; 
    self.links = ko.observableArray([ 
     new LinkModel({ name: "link1"}), 
     new LinkModel({ name: "link2"}) 
    ]); 
}; 

$(function() { 
    //registration of the custom element 
    ko.components.register('settings-view-link', 
    { 
     viewModel: LinkModel, 
     template: "<div><strong data-bind='text: name'></strong></div>" 
    }); 
    ko.applyBindings(new MainModel()); 
}); 
<div> 
    <ul data-bind="foreach: links"> 
     <p data-bind="text: name"></p> <!-- handled correctly --> 
     <settings-view-link></settings-view-link> <!-- handled not the way I expect--> 
    </ul> 
</div> 

Что я вижу в том, что если в пользовательском элементе нужно использовать $ родителю. чтобы моя привязка данных работала, как ожидалось. Использование

<div><strong data-bind='text: $parent.name'></strong></div> 

вместо

<div><strong data-bind='text: name'></strong></div> 

делает появляться имя моей ссылки на веб-странице.

Я ожидал, что внутри пользовательского элемента он обрабатывает объект LinkModel, но это не так, это как-то «подмодель». Может кто-нибудь объяснить, почему я должен использовать $ parent? Код неправильный, но почему? Я действительно ожидаю наличия объекта LinkModel внутри моего пользовательского элемента.

Большое спасибо

ответ

1

Поскольку пользовательский компонент определяет viewModel вариант, Нокаут создаст новый экземпляр этого ViewModel для вас. Вы можете опустить свойство, и нокаут привяжет компонент к предоставленным параметрам:

Компоненты обычно имеют модели, но они необязательно должны. Компонент может указывать только шаблон. В этом случае объект, к которому вид компонента будет связано это PARAMS объект, который вы прошли к компоненту связывания

Источник: http://knockoutjs.com/documentation/component-binding.html#note-template-only-components

Этот пример может лучше объяснить, что я имею в виду. Первый компонент определяет функцию viewmodel, которая создается и привязывается к экземпляру компонента.

Второй компонент передает $data в качестве параметра и в основном работает как шаблон. Вам может потребоваться привязка шаблона, если вы не хотите автоматически создавать новые режимы просмотра.

var instanceCounter = 0; 
 

 
var ViewModel = function() { 
 
    this.nr = instanceCounter++; 
 
} 
 

 
ko.components.register('testComponent1', { 
 
    viewModel: ViewModel, 
 
    template: '<div data-bind="text: nr"></div>' 
 
}); 
 

 
ko.components.register('testComponent2', { 
 
    template: '<div data-bind="text: nr"></div>' 
 
}); 
 

 

 
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 

 
<section> 
 
    <h2>New instance for each component</h2> 
 
    <div data-bind='component: { 
 
    name: "testComponent1" 
 
}'></div> 
 
    <div data-bind='component: { 
 
    name: "testComponent1" 
 
}'></div> 
 
    <div data-bind='component: { 
 
    name: "testComponent1" 
 
}'></div> 
 
</section> 
 

 
<section> 
 
    <h2>Same instance for each component</h2> 
 
    <div data-bind='component: { 
 
    name: "testComponent2", 
 
    params: $data 
 
}'></div> 
 
    <div data-bind='component: { 
 
    name: "testComponent2", 
 
    params: $data 
 
}'></div> 
 
    <div data-bind='component: { 
 
    name: "testComponent2", 
 
    params: $data 
 
}'></div> 
 
</section>

+0

Большое спасибо, это работает! – Seamus