【问题标题】:Defining a function on KnockoutJS ViewModel在 Knockout JS ViewModel 中定义一个函数
【发布时间】:2017-08-30 03:45:10
【问题描述】:

在 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;
});

我做错了什么?

【问题讨论】:

  • 您应该在链接到您的posts 调用的.done() 函数中初始化您的selectedUser
  • 就是这样!谢谢@cl3m

标签: javascript knockout.js


【解决方案1】:

您的问题来自您的 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>

【讨论】:

    猜你喜欢
    • 2014-03-28
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 2023-04-11
    • 2018-07-03
    • 1970-01-01
    相关资源
    最近更新 更多