2015-10-06 5 views
2

Я пытаюсь использовать пользовательские элементы нокаута в своем приложении, но у меня есть одна проблема. У меня есть два вложенных пользовательских элемента, и я хочу, чтобы они общались. Я пытался поделиться наблюдаемым между ними, но я постоянно получаю сообщение об ошибке: Unable to process binding "template: function(){return { nodes:$componentTemplateNodes} } Message: someVariable is not defined - внутренний компонент не может получить доступ к наблюдаемому. Как это исправить? Или, может быть, есть лучший способ общения между вложенными компонентами? Я использую нокаута 3.3.0Связь между вложенными компонентами в Knockout.js

мой код:

HTML:

<parent-component params="variable: someVariable"> 
    <child-component params="variable: someVariable"></child-component> 
</parent-component> 

ЯШ:

ko.components.register("parent-component", { 
    viewModel: function (params) { 
     this.params = params; 
    }, 
    template: "<div data-bind='text: params.variable'></div> <!-- ko template: { nodes: $componentTemplateNodes } --><!-- /ko -->" 
}); 

ko.components.register("child-component", { 
    viewModel: function (params) { 
     this.params = params; 
    }, 
    template: "<div data-bind='text: params.variable'></div>" 
}); 

ko.applyBindings({ 
    someVariable: ko.observable(true) 
}); 

демо:http://jsfiddle.net/50zbtxe3/

ответ

1

Дело в том, что внутри «родительского компонента» не существует «someVariable». Вы должны передать его на следующий уровень связывания:

ko.components.register("parent-component", { 
viewModel: function (params) { 
    this.params = params; 
    this.someVariable = params.variable; 
}, 
template: "<div data-bind='text: params.variable'></div> <!-- ko template: { nodes: $componentTemplateNodes } --><!-- /ko -->" 
}); 

Я обновил jsfiddle: http://jsfiddle.net/50zbtxe3/1/

1

Проблема в том, что DataContextchild-component не является корневой моделью. Поэтому вам нужно напрямую ссылаться на корневую модель. Как это:

<parent-component params="variable: someVariable"> 
    <child-component params="variable: $root.someVariable"></child-component> 
</parent-component> 

Контекст child-component является viewmodel из parent-component, который не имеет someVariable свойство.

2

Я бы порекомендовал привязки вложенного шаблона в $parent рамки, если вам нужно только простой контейнер

ko.components.register("parent-container", { 
 
viewModel: function (params) { 
 
    this.params = params; 
 
}, 
 
template: "<div data-bind='style: { color: params.color }'>Header</div> <!-- ko template: { nodes: $componentTemplateNodes, data: $parent } --><!-- /ko -->" 
 
}); 
 

 
var model = { 
 
    someVariable: 'test' 
 
} 
 

 
ko.applyBindings();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script> 
 
<parent-container params="color: 'red'"> 
 
    <div data-bind="text: someVariable">asdasdsad</div> 
 
</parent-container> 
 

 
<parent-container params="color: 'blue'"> 
 
    <div data-bind="text: someVariable2">asdasdsad</div> 
 
</parent-container>

+0

Лучший ответ на сегодняшний день. Простой, хранящийся в компоненте упаковки, чтобы дети не имели дело с родительским макетом. Люблю это! – k2snowman69

+0

Спасибо, @ k2snowman69 работают слишком много раз со сложными решениями, написанными мной :) – codevision

2

еще одна о ption - использовать будущее , позволяющее переводить, которое будет выходить на более поздней итерации нокаута. Это позволит вам сделать следующее в компоненте прародителя:

<!-- ko let: { $parentComponent: $component } --> 
<parent-component params="variable: $component.someVariable"> 
    <child-component params="variable: $parentComponent.someVariable"></child-component> 
</parent-component> 
<!-- /ko --> 

основном позволяет получить доступ к родительскому компоненту от другого компонента.

Выпускаемое связывания код можно найти здесь: https://github.com/knockout/knockout/blob/241c26ca82e6e4b3eaee39e3dc0a92f85bc1df0c/src/binding/defaultBindings/let.js

Смежные вопросы