在KnockoutJs中,我有一个我正在处理的管理页面的以下ViewModel:
function UsersViewModel() {
var self = this;
self.users = ko.observableArray([]);
self.roles = ko.observableArray([]);
$.post('http://localhost:23926/admin/acl/getroles',
function(data) {
const availableRoles = $.map(data,
function(role) {
return new Role(role);
});
self.roles(availableRoles);
},
'json');
$.post('http://localhost:23926/admin/acl/getuserroles',
function(data) {
const usersWithRoles = $.map(data,
function(userWithRole) {
return new User(userWithRole);
});
self.users(usersWithRoles);
},
'json');
self.selectedUser = ko.observable(self.users[0]);
// operations
self.setCurrentUser = function (user) {
self.selectedUser(user);
}
self.SelectedUserHasRoles = ko.computed(function() {
return self.selectedUser().roles().length > 0;
});
}
在我的HTML中,我有以下内容:
<div class="col-md-6" data-bind="if: $root.SelectedUserHasRoles()">
<h4><i class="fa fa-shield" aria-hidden="true"></i> Roles</h4>
<hr />
<div id="roles-wrapper" data-bind="foreach: $root.selectedUser().roles">
<div class="role-token" data-bind="text: name"></div>
</div>
</div>
我觉得应该有用!我想说:
如果所选用户有角色,则循环,显示每个角色
如果这样有效,我会在左侧看到用户,在右侧看到所选用户的角色:
以上似乎不起作用,我不知道为什么!我收到错误:
第343行是这里的回归:
self.SelectedUserHasRoles = ko.computed(function() {
return self.selectedUser().roles().length > 0;
});
我做错了什么?
答案 0 :(得分:2)
您的问题来自于selectedUser
为空,因为您使用空数组的第一个元素将其初始化:
self.users = ko.observableArray([]);
// => self.users[0] === null, and maybe you should use self.users()[0]
self.selectedUser = ko.observable(self.users[0]);
要避免此问题,您可以添加加载布尔值以指示您的应用程序未完成加载用户,或添加Promise.all
调用,然后添加您的初始化逻辑。
使用承诺:
var promises = [$.post(...), $.post(...)]
Promise.all(promises).then(function(data) {
// ... users and roles initalisation
self.selectedUser(self.users()[0]);
})
// or via chained done method
$.post(...).done(function() {
self.selectedUser(self.users()[0]);
})
或使用布尔逻辑(您可以优化此未经测试的代码):
self.loading = ko.observableArray(false)
self.isLoaded = ko.pureComputed(function() {
return self.loading().all(function(x) { return x }) // ES5 syntax
})
self.selectedUser = ko.pureComputed(function() {
if (self.isLoaded()) return users()[0]
return null
})
$.post('..roles', function() {
// ...
self.loading()[0] = true
})
$.post('..users', function() {
// ...
self.loading()[1] = true
})
并在您的HTML中:
<div class="col-md-6" data-bind="if: $root.SelectedUserHasRoles()">
<h4><i class="fa fa-shield" aria-hidden="true"></i> Roles</h4>
<hr />
<!-- ko if: !isLoaded() -->
<span>Loading !</span>
<!-- /ko -->
<!-- ko if: isLoaded() -->
<div id="roles-wrapper" data-bind="foreach: $root.selectedUser().roles">
<div class="role-token" data-bind="text: name"></div>
</div>
<!-- /ko -->
</div>