Я использую HotTowel для создания SPA, но у меня проблемы с проверкой привязки Knockout для работы с коллекцией Breeze.Нокаут проверен на привязку и детские коллекции Breeze
У меня есть список пользователей и список групп. Я хочу иметь возможность добавлять или удалять пользователей в группы, установив флажок.
Если я правильно понимаю, я должен использовать проверенное связывание с наблюдаемым массивом с опцией 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 из UserGroups not Groups, поэтому я знаю, что я не могу просто привязать свойство Groups к флажкам напрямую.
Я попытался создать пользовательский конструктор для моего объекта User, чтобы я мог производить вычисляемый наблюдаемый массив только групп для меня, чтобы использовать вместо этого. Однако, когда конструктор создан, ни один из свойств User, похоже, не существует, и мой вычисленный наблюдаемый не обновляется после их создания.
Возможно ли это, или я не ошибаюсь?
Вот вырезка моей неудачной попытки 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>
Я написал свое собственное решение вместо этого ответа, похожего на него. Однако, прочитав его, я переписал его гораздо эффективнее, так что ура. В основном RTFM. – JamesT