Knockoutjs: 从 child 组件调用 parent 组件的函数
Knockoutjs: Invoking function of parent component from child component
问题:
我正在尝试构建一个小部件仪表板。每个小部件的 header 上都有一个删除按钮。单击此按钮时,相应的小部件必须消失。
我是如何设计的:
我有两个淘汰组件。
- my-widget-list:
VO 将有一个 widget objects.
的 observableArray
- my-widget:
VO 将在小部件中显示详细信息。
注意:为简单起见,我将小部件 object 替换为数字。
ko.components.register('my-widget-list', {
viewModel : function(params) {
var self = this;
self.values = ko.observableArray([10,20,30,40,50]);
self.deleteWidget = function(obj)
{
self.values.remove(obj);
}
},
template: {element: 'my-widget-list-template'}
});
ko.components.register('my-widget', {
viewModel : function(params) {
var self = this;
self.value = params.value;
},
template: {element: 'my-widget-template'}
});
ko.applyBindings({});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<my-widget-list></my-widget-list>
<script id="my-widget-list-template" type="text/html">
<div data-bind="foreach:values">
<my-widget params="value: $data"></my-widget><br>
</div>
</script>
<script id="my-widget-template" type="text/html">
<span data-bind="text: value"></span>
<button data-bind="click: $parent.deleteWidget">Delete</button>
</script>
现在,我想在单击按钮时调用 my-widget-list
的 deleteWidget
函数。
我考虑过
- 将 parent 视图模型引用传递到 child
- 将child组件的params属性中的parent函数作为回调传递
但我想从专家那里了解实现这一目标的最佳方法是什么。
提前致谢
您可以将 parent 作为参数传递给 child:
ko.components.register('my-widget-list', {
viewModel : function(params) {
var self = this;
self.values = ko.observableArray([10,20,30,40,50]);
self.deleteWidget = function(obj) {
self.values.remove(obj);
}
},
template: {element: 'my-widget-list-template'}
});
ko.components.register('my-widget', {
viewModel : function(params) {
var self = this;
self.value = params.value;
self.remove = function () {
params.parent.deleteWidget(self.value);
};
},
template: {element: 'my-widget-template'}
});
ko.applyBindings({});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<my-widget-list></my-widget-list>
<script id="my-widget-list-template" type="text/html">
<div data-bind="foreach:values">
<my-widget params="value: $data, parent: $parent"></my-widget><br>
</div>
</script>
<script id="my-widget-template" type="text/html">
<span data-bind="text: value"></span>
<button data-bind="click: remove">Delete</button>
</script>
但我不确定这是否是个好主意,因为它不必要地将 child 耦合到 parent。
我建议在 parent 中实现 "remove" 按钮,即在 <my-widget-list>
中,这样小部件就可以在没有 widget-list 的情况下存在(或在结构不同的一个),而 widget-list 控制着它的 children。
比较window 经理:他们的工作方式相同。 window 管理器绘制框架和 minimize/maximize/close 按钮,而 window 内容由相应的 child 进程绘制。该逻辑在您的场景中也有意义。
在 parent 中使用 removeWidget
控件的替代实现:
ko.components.register('my-widget-list', {
viewModel : function(params) {
var self = this;
self.values = ko.observableArray([10,20,30,40,50]);
self.deleteWidget = function(obj) {
self.values.remove(obj);
}
},
template: {element: 'my-widget-list-template'}
});
ko.components.register('my-widget', {
viewModel : function(params) {
var self = this;
self.value = params.value;
},
template: {element: 'my-widget-template'}
});
ko.applyBindings({});
.widget-container {
position: relative;
display: inline-block;
padding: 10px 5px 5px 5px;
margin: 0 5px 5px 0;
border: 1px solid silver;
border-radius: 2px;
min-width: 40px;
}
.widget-buttons {
position: absolute;
top: 2px;
right: 2px;
}
.widget-buttons > button {
font-size: 2px;
padding: 0;
height: 15px;
width: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<my-widget-list></my-widget-list>
<script id="my-widget-list-template" type="text/html">
<div class="widget-list" data-bind="foreach:values">
<div class="widget-container">
<div class="widget-buttons">
<button data-bind="click: $parent.deleteWidget">X</button>
</div>
<my-widget params="value: $data"></my-widget>
</div>
</div>
</script>
<script id="my-widget-template" type="text/html">
<div class="widget">
<span data-bind="text: value"></span>
</div>
</script>
问题: 我正在尝试构建一个小部件仪表板。每个小部件的 header 上都有一个删除按钮。单击此按钮时,相应的小部件必须消失。
我是如何设计的: 我有两个淘汰组件。
- my-widget-list: VO 将有一个 widget objects. 的 observableArray
- my-widget: VO 将在小部件中显示详细信息。
注意:为简单起见,我将小部件 object 替换为数字。
ko.components.register('my-widget-list', {
viewModel : function(params) {
var self = this;
self.values = ko.observableArray([10,20,30,40,50]);
self.deleteWidget = function(obj)
{
self.values.remove(obj);
}
},
template: {element: 'my-widget-list-template'}
});
ko.components.register('my-widget', {
viewModel : function(params) {
var self = this;
self.value = params.value;
},
template: {element: 'my-widget-template'}
});
ko.applyBindings({});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<my-widget-list></my-widget-list>
<script id="my-widget-list-template" type="text/html">
<div data-bind="foreach:values">
<my-widget params="value: $data"></my-widget><br>
</div>
</script>
<script id="my-widget-template" type="text/html">
<span data-bind="text: value"></span>
<button data-bind="click: $parent.deleteWidget">Delete</button>
</script>
现在,我想在单击按钮时调用 my-widget-list
的 deleteWidget
函数。
我考虑过
- 将 parent 视图模型引用传递到 child
- 将child组件的params属性中的parent函数作为回调传递
但我想从专家那里了解实现这一目标的最佳方法是什么。
提前致谢
您可以将 parent 作为参数传递给 child:
ko.components.register('my-widget-list', {
viewModel : function(params) {
var self = this;
self.values = ko.observableArray([10,20,30,40,50]);
self.deleteWidget = function(obj) {
self.values.remove(obj);
}
},
template: {element: 'my-widget-list-template'}
});
ko.components.register('my-widget', {
viewModel : function(params) {
var self = this;
self.value = params.value;
self.remove = function () {
params.parent.deleteWidget(self.value);
};
},
template: {element: 'my-widget-template'}
});
ko.applyBindings({});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<my-widget-list></my-widget-list>
<script id="my-widget-list-template" type="text/html">
<div data-bind="foreach:values">
<my-widget params="value: $data, parent: $parent"></my-widget><br>
</div>
</script>
<script id="my-widget-template" type="text/html">
<span data-bind="text: value"></span>
<button data-bind="click: remove">Delete</button>
</script>
但我不确定这是否是个好主意,因为它不必要地将 child 耦合到 parent。
我建议在 parent 中实现 "remove" 按钮,即在 <my-widget-list>
中,这样小部件就可以在没有 widget-list 的情况下存在(或在结构不同的一个),而 widget-list 控制着它的 children。
比较window 经理:他们的工作方式相同。 window 管理器绘制框架和 minimize/maximize/close 按钮,而 window 内容由相应的 child 进程绘制。该逻辑在您的场景中也有意义。
在 parent 中使用 removeWidget
控件的替代实现:
ko.components.register('my-widget-list', {
viewModel : function(params) {
var self = this;
self.values = ko.observableArray([10,20,30,40,50]);
self.deleteWidget = function(obj) {
self.values.remove(obj);
}
},
template: {element: 'my-widget-list-template'}
});
ko.components.register('my-widget', {
viewModel : function(params) {
var self = this;
self.value = params.value;
},
template: {element: 'my-widget-template'}
});
ko.applyBindings({});
.widget-container {
position: relative;
display: inline-block;
padding: 10px 5px 5px 5px;
margin: 0 5px 5px 0;
border: 1px solid silver;
border-radius: 2px;
min-width: 40px;
}
.widget-buttons {
position: absolute;
top: 2px;
right: 2px;
}
.widget-buttons > button {
font-size: 2px;
padding: 0;
height: 15px;
width: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<my-widget-list></my-widget-list>
<script id="my-widget-list-template" type="text/html">
<div class="widget-list" data-bind="foreach:values">
<div class="widget-container">
<div class="widget-buttons">
<button data-bind="click: $parent.deleteWidget">X</button>
</div>
<my-widget params="value: $data"></my-widget>
</div>
</div>
</script>
<script id="my-widget-template" type="text/html">
<div class="widget">
<span data-bind="text: value"></span>
</div>
</script>