HTML with bindings:
<div class="container" data-bind="foreach: { data: Conferences, as: 'conf' }">
<div class="conf" data-bind="attr: { id : conf.Id }">
<div class="conf-month" data-bind="text: conf.StartTime"></div>
<div class="conf-day" data-bind="text: conf.EndTime"></div>
<div class="add-user">
<input type="tel" data-bind="value: $root.PhoneNumber />
<input type="email" data-bind="value: $root.Email" />
<a id="add-user" title="Add new user" data-bind="attr: { value: conf.Id }, click: $root.addUserToConference">Add</a>
</div>
<div class="conf-users" data-bind="foreach: { data: conf.ConferenceUsers, as: 'user' }">
<div class="conf-user" data-bind="attr: { id: 'confuser-' + user.Id}">
<span data-bind="text: user.Name"></span>
<span data-bind="text: user.PhoneNumber"></span>
<span data-bind="text: user.Email"></span>
</div>
</div>
</div>
</div>
KnockoutJs ViewModel:
function ConferenceViewModel() {
var self = this;
self.Conferences = ko.observableArray([]);
self.PhoneNumber = ko.observable("");
self.Email = ko.observable("");
self.getAllConfs = function () {
$.ajax({
type: 'GET',
url: '/confs/getconfs',
}).done(function (confs) {
$.each(confs, function (index, conf) {
//populate the list on document ready
confVm.Conferences.push(conf);
};
}).fail(showError);
}
self.addUserToConference = function (viewModel, event) {
var user = {
"Id": 0,
"ConferenceId": viewModel.Id(),
"Email": "self.Email()",
"PhoneNumber": self.PhoneNumber(),
};
// here we should insert a new ConferenceUser into the Conferences observable array
// and also update the DOM
// ajax to insert user to db
}
After I populate the above Conferences observableArray via ajax, the output of console.log(ko.toJSON(confVm.Conferences()))
is as follows:
[
{
"ConferenceUsers":[
{
"Id":3006,
"ConferenceId":8,
"Name":null,
"Email":"mail@lala.com",
"UserName":null,
"PhoneNumber":"234234234234",
"ChannelId":null,
"State":null,
"Type":null,
"RecordingId":null
}
],
"Id":8,
"Subject":"YYYhaaaaa",
"StartTime":"2016-05-29T18:30:00",
"EndTime":"2016-05-29T19:30:00",
"OrganizerEmail":"elpas@live.com",
"OrganizerName":"dasdasd",
"Pin":"6402",
"BridgeId":null,
"State":null
},
{
"ConferenceUsers":[
{
"Id":3013,
"ConferenceId":12,
"Name":null,
"Email":"dsfdfsdfdsf@dfdfdf.com",
"UserName":null,
"PhoneNumber":null,
"ChannelId":null,
"State":null,
"Type":null,
"RecordingId":null
}
],
"Id":12,
"Subject":"dsfsdfdsfsdf",
"StartTime":"2016-05-31T22:00:00",
"EndTime":"2016-05-31T23:00:00",
"OrganizerEmail":"d@adssad.com",
"OrganizerName":"dsfdsfsdf",
"Pin":"3402",
"BridgeId":null,
"State":null
}
]
Q: How can I insert a new ConferenceUser by ConferenceId and update the DOM accordingly?
Try this:
var obj = [
{
"ConferenceUsers":[
{
"Id":3006,
"ConferenceId":8,
"Name":null,
"Email":"mail@lala.com",
"UserName":null,
"PhoneNumber":"234234234234",
"ChannelId":null,
"State":null,
"Type":null,
"RecordingId":null
}
],
"Id":8,
"Subject":"YYYhaaaaa",
"StartTime":"2016-05-29T18:30:00",
"EndTime":"2016-05-29T19:30:00",
"OrganizerEmail":"elpas@live.com",
"OrganizerName":"dasdasd",
"Pin":"6402",
"BridgeId":null,
"State":null
},
{
"ConferenceUsers":[
{
"Id":3013,
"ConferenceId":12,
"Name":null,
"Email":"dsfdfsdfdsf@dfdfdf.com",
"UserName":null,
"PhoneNumber":null,
"ChannelId":null,
"State":null,
"Type":null,
"RecordingId":null
}
],
"Id":12,
"Subject":"dsfsdfdsfsdf",
"StartTime":"2016-05-31T22:00:00",
"EndTime":"2016-05-31T23:00:00",
"OrganizerEmail":"d@adssad.com",
"OrganizerName":"dsfdsfsdf",
"Pin":"3402",
"BridgeId":null,
"State":null
}
];
/* Iterate all conferences */
for (var i in obj) {
/* Find conference with ID = 8 */
if (obj[i].Id === 8) {
/* Add a new user to the conference */
obj[i].ConferenceUsers.push({
"Id":1111,
"ConferenceId":1,
"Name":null,
"Email":"test@example.com",
"UserName":null,
"PhoneNumber":null,
"ChannelId":null,
"State":null,
"Type":null,
"RecordingId":null
});
break;
}
}
console.log(obj); // output result
You'll need to execute four steps:
Conferences
ConferenceUsers
Conferences
is set with the new data While all steps are pretty straight forward to execute, there'll be some drawbacks to how they'd work:
The Conference
objects and the ConferenceUsers
arrays aren't observable. Knockout isn't automatically aware of any changes inside the Conference
objects. So, after step 3 and 4 , to knockout, it won't appear as if anything's changed: the Conferences
array still has the same objects in it.
My advice:
If adding new users to conferences is something that will happen regularly, I'd suggest creating a Conference
viewmodel that has a ko.observableArray
of users. Alternatively, you could create new Conference
objects for every minor change, which will trigger knockout to re-render the entire UI instead of just the relevant part (assuming you've used a foreach
data-bind somewhere).
A quick example of how you could map your regular Conference
objects to viewmodels:
// Your JSON data from the ajax request (an array of objects) var conferencesData = []; var Conference = function(conferenceJSON) { // It's better to map all properties you're using individually, // but this at least exposes the original JSON object this.props = conferenceJSON; this.users = ko.observableArray(conferenceJSON.conferenceUsers); }; var createConference = function(conferenceJSON) { return new Conference(conferenceJSON); }; var ConferenceList = function(conferencesJSON) { var self = this; this.conferences = ko.observableArray(conferencesJSON.map(createConference)); this.addConference = function(conferenceJSON) { self.conferences.push(createConference(conferenceJSON)); }; this.addUserToConference = function(userJSON) { var conferences = self.conferences(); for (var c = 0; c < conferences.length; c += 1) { // Step 2: Find the conference with the required id if (conferences[c].props.id === userJSON.ConferenceId) { // Step 3: We're pushing to an observableArray, so no need // to worry about Step 4. conferences[c].users.push(userJSON); return true; } } return false; }; }; ko.applyBindings(new ConferenceList(conferencesData));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.