http://stackoverflow.com/questions/43123785/knockout-observable-array-not-being-observed
by jlspake
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
Is Loaded: <span data-bind="text: isLoaded"></span><br/>
Has Roles: <span data-bind="text: SelectedUserHasRoles()"></span><br/>
selectedUser: <span data-bind="text: ko.toJSON($root.selectedUser())"></span><br/>
<!-- ko if: isLoaded -->
<h3 data-bind="text: $root.selectedUser().username"></h3>
<!-- ko if: SelectedUserHasRoles() -->
<div class="roles-wrapper" data-bind="foreach: $root.selectedUser().roles()">
<div class="role-token" data-bind="text: name()"></div>
</div>
<!-- /ko -->
<!-- /ko -->
JavaScript
function UsersViewModel() {
var self = this;
// data with some removed for brevity
self.isLoaded = ko.observable(false);
self.users = ko.observableArray([]);
self.roles = ko.observableArray([{name: 'Admin'}, {name: 'Minion'}]);
self.userAvailableRoles = ko.observableArray([]);
self.selectedUser = ko.observable();
self.SelectedUserHasRoles = ko.computed(function () {
if (self.isLoaded()) {
return self.selectedUser().roles().length > 0;
}
return false;
});
self.UserHasAllAvailableRoles = ko.computed(function () {
if (self.isLoaded()) {
return self.userAvailableRoles().length === 0;
}
return false;
});
// isLoaded gets set to true when AJAX call to server
// is a success and data is returned
// operations with some removed for brevity
self.setCurrentUser = function (user) {
const newRolesArray = self.roles().filter(function (role) {
//return !contains(user.roles(), role);
return user.roles().indexOf(role) >= 0;
});
self.userAvailableRoles(newRolesArray);
self.selectedUser(user);
self.isLoaded(true);//Debugging bypass
}
self.newUsernameText = ko.observable('New User');
self.addUser = function () {
self.users.push(new User({ Username: this.newUsernameText(), Roles: [{name: 'Minion'}] }));
self.newUsernameText('');
//self.NewUserFormIsVisible(false);
//self.AddRolesFormIsVisible(true);
self.setCurrentUser(self.users()[self.users().length - 1]);
};
}
function User(data){
var self = this;
this.username = ko.observable(data.Username);
this.roles = ko.mapping.fromJS(data.Roles);
setTimeout(function(){
self.roles.push({name: ko.observable('Admin')});
}, 1000);
}
var viewModel = new UsersViewModel();
ko.applyBindings(viewModel);
setTimeout(function(){
viewModel.addUser();
}, 500)