Reputation: 15237
Let me start with a screencast of the current behaviour. As you can see, when I add a role for the user jbrown, the role doesn't show where it should!
But if I navigate away to another user, then back to jbrown, the role(s) does show!
Here is the ViewModel in question:
function UsersViewModel() {
var self = this;
// data with some removed for brevity
self.isLoaded = ko.observable(false);
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);
});
self.userAvailableRoles(newRolesArray);
self.selectedUser(user);
}
self.addUser = function () {
self.users.push(new User({ Username: this.newUsernameText() }));
self.newUsernameText('');
self.NewUserFormIsVisible(false);
self.AddRolesFormIsVisible(true);
self.setCurrentUser(self.users()[self.users().length - 1]);
};
self.addRoleForSelectedUser = function() {
self.selectedUser().roles().push(new Role({ Name: self.selectedRole().name() }));
self.AddRolesFormIsVisible(false);
$.post('http://localhost:23926/admin/acl/addusertorole', { username: self.selectedUser().name(), role: self.selectedRole().name() },
function () {
console.log('user role created at db!');
},
'json');
}
}
And here is the HTML markup in question:
<!-- ko if: isLoaded -->
<!-- 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 -->
My Observable array of roles must be getting populated because as you saw, when I navigate away and back, I can see the roles I've added.
What am I missing?
Upvotes: 0
Views: 31
Reputation: 43881
Instead of
self.selectedUser().roles().push(
do
self.selectedUser().roles.push(
That will use the ObservableArray member function push
rather than the underlying array's push
. The difference is that Knockout only notices the changes made through its member functions.
Upvotes: 1
Reputation: 4304
You're trying to push the new role to the underlying, untracked, array instead of the observable array.
self.addRoleForSelectedUser = function() {
self.selectedUser().roles().push(new Role({ Name: self.selectedRole().name() }));
...
}
You just need to remove the set of parenthesis after "roles" so that it looks like:
self.selectedUser().roles.push(new Role({ Name: self.selectedRole().name() }));
Upvotes: 1