Knockout 组件 - 跨组件传递值
Knockout Component - Pass value across components
我是 Knockout JS 的新手,正在学习组件的工作原理。
我创建了两个组件来创建员工和显示已创建员工的列表。
但我面临几个问题:
问题 # 1: 按钮的点击事件没有触发
问题#2: employee 创建后,我想在另一个组件中反映所有创建的员工。
我已经尝试过,如下例所示
示例: JSFiddle
源代码:
/********************* COMPONENT-1 ************************/
ko.components.register('emp-list', {
viewModel: function(params) {
var self = this;
self.Name = ko.observable();
self.Name(params.EmpName.firstName + ', ' + params.EmpName.lastName);
},
template: '<div class="name-container"><span data-bind="html: Name"></span></div>'
});
/********************* COMPONENT-2 ************************/
ko.components.register('emp-create', {
viewModel: function(params) {
var self = this;
self.firstName = ko.observable(),
self.lastName = ko.observable(),
self.EmpList = ko.observableArray(),
self.AddEmp = function()
{
alert('1');
self.Emplist.push(self.firstName() + ' ' + self.lastName());
for( i=0; i< self.Emplist(); i++)
{
alert(self.Emplist()[i]);
}
}
},
template: '<div class="create"><input type="text" placeholder="First name" data-bind="text: firstName" /><input type="text" data-bind="text:lastName" placeholder="Last name" /><input type="button" value="Add" data-bind="click: $root.AddEmp" /></div>'
});
/******************** VIEW MODEL ************************/
var vm = function() {
var self = this;
self.Emps = [{'Details': {firstName: 'First Name-A', lastName: 'Last Name-A'}},
{'Details': {firstName: 'First Name-B', lastName: 'Last Name-B'}}];
}
ko.applyBindings(new vm());
.name-container{
padding: 5px;
margin: 2px;
background-color: #cacaca;
border: 1px solid #888;
border-radius: 5px;
}
.name-container span {
margin: 5px;
}
body {
font-family: arial,sans-serif;
font-size: 13px;
}
.action {
cursor: pointer;
color: blue;
text-decoration: underline;
}
.create {
background-color: #cacaca;
padding: 5px;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<div data-bind='component: {name: "emp-create"}'>
</div>
<div data-bind='foreach: Emps'>
<div data-bind='component: {
name: "emp-list",
params: {EmpName: Details}
}'></div>
</div>
在您的 ViewModel self.Emps
中是一个数组,它应该是一个可观察的数组,以便在添加新员工时刷新 UI(部分解决 问题#2):
self.Emps = ko.observableArray(
[{'Details': {firstName: 'First Name-A',
lastName: 'Last Name-A'}},
{'Details': {firstName: 'First Name-B',
lastName: 'Last Name-B'}}]
);
现在,您需要将 Emps
传递给 emp-create
组件才能添加新元素(也解决了 问题#2):
<div data-bind='component: {name: "emp-create",
params: {EmpList: Emps}}'>
</div>
在 emp-create
的 ViewModel 中,更改:
self.EmpList = ko.observableArray(),
至
self.EmpList = params.EmpList,
self.AddEmp
函数有错别字。它有 self.Emplist.push
,应该是 self.EmpList.push
(EmpList)。
emp-create
组件中的点击绑定错误,有click: $root.AddEmp
应该是click: AddEmp
(没有$root
)。它解决了问题#1
self.AddEmp
函数应该添加一个员工:
self.AddEmp = function()
{
self.EmpList.push(
{'Details': {firstName: self.firstName(),
lastName: self.lastName()}}
)
}
这是更新后的 fiddle
更新:
您的 emp-create
模板在 <input type="text">
中的绑定有误。您有 data-bind="text: firstName"
,它应该是 data-bind="value: firstName"
,也就是说,您需要将 text
更改为 value
,以便从 <input>
更新可观察对象。这里 Value Binding 更多信息。
这是更新后的 fiddle。
我是 Knockout JS 的新手,正在学习组件的工作原理。
我创建了两个组件来创建员工和显示已创建员工的列表。
但我面临几个问题:
问题 # 1: 按钮的点击事件没有触发
问题#2: employee 创建后,我想在另一个组件中反映所有创建的员工。
我已经尝试过,如下例所示
示例: JSFiddle
源代码:
/********************* COMPONENT-1 ************************/
ko.components.register('emp-list', {
viewModel: function(params) {
var self = this;
self.Name = ko.observable();
self.Name(params.EmpName.firstName + ', ' + params.EmpName.lastName);
},
template: '<div class="name-container"><span data-bind="html: Name"></span></div>'
});
/********************* COMPONENT-2 ************************/
ko.components.register('emp-create', {
viewModel: function(params) {
var self = this;
self.firstName = ko.observable(),
self.lastName = ko.observable(),
self.EmpList = ko.observableArray(),
self.AddEmp = function()
{
alert('1');
self.Emplist.push(self.firstName() + ' ' + self.lastName());
for( i=0; i< self.Emplist(); i++)
{
alert(self.Emplist()[i]);
}
}
},
template: '<div class="create"><input type="text" placeholder="First name" data-bind="text: firstName" /><input type="text" data-bind="text:lastName" placeholder="Last name" /><input type="button" value="Add" data-bind="click: $root.AddEmp" /></div>'
});
/******************** VIEW MODEL ************************/
var vm = function() {
var self = this;
self.Emps = [{'Details': {firstName: 'First Name-A', lastName: 'Last Name-A'}},
{'Details': {firstName: 'First Name-B', lastName: 'Last Name-B'}}];
}
ko.applyBindings(new vm());
.name-container{
padding: 5px;
margin: 2px;
background-color: #cacaca;
border: 1px solid #888;
border-radius: 5px;
}
.name-container span {
margin: 5px;
}
body {
font-family: arial,sans-serif;
font-size: 13px;
}
.action {
cursor: pointer;
color: blue;
text-decoration: underline;
}
.create {
background-color: #cacaca;
padding: 5px;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<div data-bind='component: {name: "emp-create"}'>
</div>
<div data-bind='foreach: Emps'>
<div data-bind='component: {
name: "emp-list",
params: {EmpName: Details}
}'></div>
</div>
在您的 ViewModel self.Emps
中是一个数组,它应该是一个可观察的数组,以便在添加新员工时刷新 UI(部分解决 问题#2):
self.Emps = ko.observableArray(
[{'Details': {firstName: 'First Name-A',
lastName: 'Last Name-A'}},
{'Details': {firstName: 'First Name-B',
lastName: 'Last Name-B'}}]
);
现在,您需要将 Emps
传递给 emp-create
组件才能添加新元素(也解决了 问题#2):
<div data-bind='component: {name: "emp-create",
params: {EmpList: Emps}}'>
</div>
在 emp-create
的 ViewModel 中,更改:
self.EmpList = ko.observableArray(),
至
self.EmpList = params.EmpList,
self.AddEmp
函数有错别字。它有 self.Emplist.push
,应该是 self.EmpList.push
(EmpList)。
emp-create
组件中的点击绑定错误,有click: $root.AddEmp
应该是click: AddEmp
(没有$root
)。它解决了问题#1
self.AddEmp
函数应该添加一个员工:
self.AddEmp = function()
{
self.EmpList.push(
{'Details': {firstName: self.firstName(),
lastName: self.lastName()}}
)
}
这是更新后的 fiddle
更新:
您的 emp-create
模板在 <input type="text">
中的绑定有误。您有 data-bind="text: firstName"
,它应该是 data-bind="value: firstName"
,也就是说,您需要将 text
更改为 value
,以便从 <input>
更新可观察对象。这里 Value Binding 更多信息。
这是更新后的 fiddle。