我有一个方法,我试图将一个子项添加到我的父项,但是当调用该方法时,调用父项的上下文是未定义的。
代码(为清晰起见缩写)小提琴http://jsfiddle.net/poundingCode/THghy/
// Initialized the namespace
var my = {};
my.models = {};
// View model declaration
my.vm = (function (model) {
var memberVm = {
id: ko.observable(model.Id),
company: ko.observable(model.Company),
fName: ko.observable(model.FName),
lName: ko.observable(model.LName),
name: ko.observable(model.Name),
positions: ko.observableArray([]),
totalPositions: ko.observable(),
totalProjects: ko.observable()
};
// children
memberVm.loadPositions = function (positions) {
memberVm.totalPositions = 0;
memberVm.totalProjects = 0;
$.each(positions, function (i, p) {
memberVm.positions.push( new my.models.Position()
.company(p.Company)
.companyId(p.CompanyId)
.description(p.Description)
.id(p.Id)
.memberId(p.MemberId)
.name(p.Name)
.title(p.Title)
.projects(p.Projects)
);
memberVm.totalPositions++;
memberVm.totalProjects += p.Projects.length;
});// end for each
}; //end load positions
memberVm.loadPositions(model.Positions);
memberVm.fullName = ko.computed(function () {
return this.fName() + ' ' + this.lName();
}, memberVm);
// Computed observable function.
// We append it to the ViewModel here.
// return object
var vm = {
id: memberVm.id,
company: memberVm.company,
fName: memberVm.fName,
fullName: memberVm.fullName,
lName: memberVm.lName,
name: memberVm.name,
positions: memberVm.positions,
totalPositions: memberVm.totalPositions,
totalProjects: memberVm.totalProjects,
};
return vm;
});
/////////////////////////////////////
// Add a position - or at least try to! this is where I get into trouble.
my.vm.addPosition = (function () {
var pos = new my.models.Position();
pos.memberId = my.vm.id;
my.vm.positions.push(pos);
});
/////////////////////////////////////
// TypeError: my.vm.positions is undefined my.vm.positions.push(pos);
my.models.Member = (function () {
id = ko.observable();
company = ko.observable();
fName = ko.observable();
lName = ko.observable();
name = ko.observable();
positions = ko.observableArray([]);
});
my.models.Position = (function () {
this.company = ko.observable();
this.id = ko.observable();
this.memberId = ko.observable();
this.name = ko.observable();
this.title = ko.observable();
// place holders
this.totalProjects = ko.observableArray();
this.totalCredits = ko.observableArray();
});
var viewModel = my.vm(data);
ko.applyBindings(viewModel);
my.setUI();
HTML
<script type="text/html" id="positionItemTemplate">
<div class="summary" data-bind="attr : {onClick: 'my.showDetails(' + id() + ')', href: '#detail_'+ id()}">
<a data-bind="attr : { href: '#detail_'+ id()}">
<h2><label data-bind="text: company().Name"></label>: <label data-bind="text: title"></label></h2> </a>
<h3><label data-bind="text: title" ></label> <label data-bind="text: startDate" ></label> - <label data-bind="value: endDate" ></label></h3>
</div>
<div data-bind="attr : {id: 'detail_' + id() }" class="details" style="right: 580px;">
<div class="positionOverview">
<h2><label data-bind="text: company().Name"></label>: <label data-bind="text: title"></label></h2> </a>
<a data-bind="attr : {href: '#detail_'+ id()}"> <div class="editor-label"><label>Position</label></div></a>
<div class="editor-field">
<input type="text" data-bind="value: company().Name" class="textbox-long">
</div>
<div class="editor-label">
<label>Title</label>
</div>
<div class="editor-field">
<input type="text" data-bind="value: title" class="textbox-long">
</div>
<div class="editor-label">
<label>Summary</label>
</div>
<div class="editor-field">
<textarea data-bind="value: summary" rows="4" cols="60"></textarea>
</div>
<div class="editor-label"><label>Compensation</label></div>
<div class="editor-field">
<select data-bind="options: $parent.compensations, value: compensationId, optionsText: 'Name', optionsValue: 'Id', optionsCaption: 'Select'"></select>
</div>
<div class="editor-label"><label for="HoursPerWeek" class="hourly">Hours/Week</label></div>
<div class="editor-field">
<input type="text" data-bind="value: hoursPerWeek" class="number-short">
</div>
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col"><label for="StartDate">Start Date</label></div>
<div class="div-table-col"><label for="EndDate">End Date</label></div>
<div class="div-table-col"></div>
</div>
<div class="div-table-row">
<div class="div-table-col"><input type="text" data-bind="value: startDate" class="date"></div>
<div class="div-table-col"><input type="text" data-bind="value: endDate" class="date"></div>
</div>
<div class="div-table-row salary">
<div class="div-table-col"><label for="SalaryStart">$/Hr Start</label></div>
<div class="div-table-col"><label for="SalaryStart">$/Hr End</label></div>
</div>
<div class="div-table-row salary">
<div class="div-table-col"><input type="text" data-bind="value: salaryStart" class="date"></div>
<div class="div-table-col"><input type="text" data-bind="value: salaryEnd" class="date"></div>
</div>
</div>
<input id="btnAddProject" type="button" value="Add Project" data-bind="attr : {onClick: 'addProject(new project())'}">
<input type="button" data-bind="attr : {onClick: 'my.showDetails(' + id() + ')'}" value="Update"/>
</div>
</div>
</script>
</head>
<body>
<div id="main">
<div class="marquee center">
<aside class="aside">
<div class="display">
<label data-bind="text: 'Total Positions: ' + totalPositions" ></label><input value="Add Position" type="button" data-bind="attr : {onClick: 'my.vm.addPosition()'}"/><br />
</div>
<div class="adPanel">
<h4><div id="message"></div></h4>
</div>
</aside>
</div>
<section id="primary" class="primary">
<article id="article1">
<section >
<div id="positions">
<div class="position" data-bind="template: { name: 'positionItemTemplate', foreach: positions, as: 'position' }">
</div>
</div>
</section>
</article>
<!-- <footer class="footer">
<p>Copyright © 2008 All Rights</p>
</footer>-->
</section>
</div>
</body>
</html>
答案 0 :(得分:2)
主要问题是您的my.vm
是一个构造函数,可用于创建my.vm
的实例。但是,addPosition
功能已直接添加到my.vm
并尝试推送到my.vm.positions
。
理想情况下,您要做的是在vm的实例上使该函数可用并推送到该实例的positions
数组。
因此,您可以将addPosition
放入vm声明中,并让它对您要返回的vm
变量进行操作。此时,当您添加新位置时,绑定会遇到问题,因为company
为空且某些绑定引用company().Name