【问题标题】:Knockout checked binding and Breeze child collections淘汰赛检查绑定和微风子集合
【发布时间】:2023-04-05 14:30:01
【问题描述】:

我正在使用 HotTowel 构建一个 SPA,但在让 Knockout 的已检查绑定与 Breeze 集合一起使用时遇到问题。

我有一个用户列表和一个组列表。我希望能够通过选中一个框来向组添加或删除用户。

如果我理解正确,我应该能够在 observableArray 上使用 checkedValue 选项的检查绑定,它会根据复选框是否被选中自动向该数组添加或删除项目。

我在服务器端有以下实体。

public class Group
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<GroupUser> Users { get; set; } 
}

public class User
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<GroupUser> Groups { get; set; }
}

而且由于 Breeze 在没有显式映射表的情况下无法处理多对多关系,所以我也有

public class UserGroup
{
    [Key, Column(Order=0)]
    [ForeignKey("User")]
    public int UserId { get; set; }

    [Key, Column(Order=1)]
    [ForeignKey("Group")]
    public int GroupId { get; set; }

    public Group Group { get; set; }
    public User User { get; set; }
}

因为我有这个映射表,所以 User.Groups 属性是用户组而不是组的 observableArray,因此我知道我不能直接将 Groups 属性绑定到复选框。

我尝试为我的用户实体创建一个自定义构造函数,以便我可以生成一个仅包含组的计算 observableArray 供我使用。但是,当创建构造函数时,似乎没有任何 User 属性存在,并且我计算的 observable 一旦更新就不会更新。

这是可能的还是我走错了路?

这是我失败的 javascript 尝试的剪辑:

var vm = {
    user: ko.observable(),
    groups: ko.observableArray();
    save: save,
    cancel: cancel
};

/* User entity constructor */
var User = function () {

    this.mappedGroups= ko.computed(function () {

        var target = this.Groups;
        var groupsArray = ko.observableArray([]);

        ko.utils.arrayForEach(target, function(userGroup) {
            groupsArray.push(userGroup.Group);
        });

        return groupsArray;
    }, this);
};

var serviceName = '/breeze/useradmin';
var store = new breeze.MetadataStore();
store.registerEntityTypeCtor('User', User);
var manager = new breeze.EntityManager({ serviceName: serviceName, metadataStore: store });

...

function loadGroups() {
    var query = breeze.EntityQuery.from('Groups');

    return manager.executeQuery(query).then(
        function (data) {
            vm.groups(data.results);
        }
    );
}

还有html:

<form>
    <input class="input-xxlarge "type="text" 
        name="name" placeholder="User Name" data-bind="value: Name" />

    <p>Groups</p>
    <div class="well well-small scroll-panel" data-bind="foreach: groups">
        <label class="checkbox">
            <input type="checkbox" data-bind="checkedValue: $data, checked:     
                $root.user.mappedGroups, attr: { value: Id }"/>
            <p data-bind="text: Description"></p>
        </label>
    </div>
    <div class="form-actions">
        <button class="btn btn-primary" data-bind="click: save">Save</button>
        <button class="btn" data-bind="click: cancel">Cancel</button>
    </div>
</form>

【问题讨论】:

    标签: javascript knockout.js breeze


    【解决方案1】:

    查看文档“Cool Breezes”部分中的"Presenting many-to-many",该部分正好涵盖了这种情况。

    示例代码适用于 Angular 应用程序。但是该指南(尤其是在 the plunker example's readme.md file 中的指南将适用于 Knockout 应用程序。

    【讨论】:

    • 我写了自己的解决方法来代替这个看起来相似的答案。然而,在阅读它之后,我更有效地重写了它,所以欢呼。基本上是 RTFM。
    猜你喜欢
    • 2012-11-25
    • 2014-04-11
    • 2013-07-29
    • 2014-03-30
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多