I have created my first KO component :
components.js
ko.components.register('team-dropdown', {
viewModel: function (params) {
var self = this;
self.teamNames = ko.observableArray([]);
$.ajax({
url: 'http://footballcomps.cloudapp.net/Teams',
type: 'get',
contentType: 'application/json',
success: function (data) {
$.each(data['value'], function (key, value) {
self.teamNames.push(value.TeamName);
});
console.dir(self.teamNames);
},
error: function (err) {
console.log(err);
}
});
self.selectedTeam = ko.observable();
},
template: { require: 'text!components/team-dropdown.html' }
});
team-dropdown.html
<div id="teams" class="inputBlock form-group">
<select class="form-control" name="teamName" data-bind="options: teamNames, value:selectedTeam"></select>
<label id="lblHomeTeam" data-bind="text: selectedTeam"></label>
And here is my view where I want to use the component :
<div class="row" id="divFixture">
<div class="col-md-4">
<div class="panel panel-info">
<div class="panel-heading">
<h2 class="panel-title">Add new fixture</h2>
</div>
<div class="panel-body">
<form data-bind="submit: fixture.addFixture">
<div class="form-group">
<team-dropdown />
</div>....
</form>
And my stripped down view model :
define(['knockout', 'knockout.validation', 'common', 'components'], function (ko) {
return function fixtureViewModel() {
function fixture(fixtureId, fixtureDate, homeId, homeName, homeBadge, homeScore, awayId, awayName, awayBadge, awayScore) {
this.FixtureId = fixtureId;
this.FixtureDate = fixtureDate;
this.HomeId = homeId;
this.HomeName = homeName;
this.HomeBadge = homeBadge;
this.HomeScore = homeScore;
this.AwayId = awayId;
this.AwayName = awayName;
this.AwayBadge = awayBadge;
this.AwayScore = awayScore;
}
var self = this;
self.Id = ko.observable();
self.FixtureDate = ko.observable();
self.HomeId = ko.observable();
self.HomeName = ko.observable();
self.HomeBadge = ko.observable();
self.HomeScore = ko.observable();
self.AwayId = ko.observable();
self.AwayName = ko.observable();
self.AwayBadge = ko.observable();
self.AwayScore = ko.observable();
self.selectedTeam = ko.observable();
self.addFixture = function() {
//how do I reference the selected item from my component here?
};
});
How do I reference the item I have selected in my component in self.addFixture?
Since the team-dropdown
is meant to be a reusable component, you should provide a way to bind to it. As you have it, it is a standalone control, the outside world cannot interact with it except through the observables you have defined which doesn't make it very flexible.
I would add parameters to it where you can set what observables to bind to the value. Your fixtures has a selectedTeam
property so that seems like a likely candidate.
ko.components.register('team-dropdown', {
viewModel: function (params) {
var self = this,
teamNames = ko.observableArray([]),
// default to a local observable if value not provided
selectedTeam = params.value || ko.observable();
// you probably don't want others to directly modify the teamNames array
self.teamNames = ko.pureComputed(teamNames);
self.selectedTeam = selectedTeam;
$.ajax({
url: 'http://footballcomps.cloudapp.net/Teams',
type: 'get',
contentType: 'application/json',
success: function (data) {
$.each(data['value'], function (key, value) {
// push to the local `teamNames` array
teamNames.push(value.TeamName);
});
console.dir(teamNames);
},
error: function (err) {
console.log(err);
}
});
},
template: { require: 'text!components/team-dropdown.html' }
});
Then set the parameter when you use the component:
<form data-bind="submit: fixture.addFixture">
<div class="form-group">
<team-dropdown params="value: fixture.selectedTeam" />
</div>
</form>
The selected value should now be set in the selectedTeam
of your fixture, so you can just use that.
self.addFixture = function() {
var selectedTeam = self.selectedTeam(); // should have the value
};