如果我試圖改變元素的樣式或可視性,我傾向於在Knockout Viewmodel中使用jQuery而後悔。所以我猜這裏有更好的方法:遞歸敲除列表 - 設置沒有jQuery的選定值
我有一些遞歸敲擊視圖模型來顯示公司的樹結構,這些公司的經理以及這些經理之下的任何公司以及(因此遞歸岬)。
我如何可以設置一個孩子(ManagerViewModel)可觀察到的從$根(ApproverViewModel)當我遞歸創建這些對象之內?目前,我正在用jQuery做這件事,並設置了隱藏元素的值,但這似乎違背了KO的可觀察模式 - 這讓我覺得還有一種更好的方式,我只是不知道。
在MangerViewModel中,我在第一次加載頁面時設置了_self.DefaultApproverClass()
。然後,當用戶選擇不同的管理器時,我只需刪除所有類,找到新選定元素的ID並將CSS類應用到它。
我猜這樣做有一個更好的,更「敲除遞歸」的方式。有什麼建議麼?
這裏是我的ViewModels(the complete version is in this JSFiddle)
be.ApproverViewModel = function (data) {
var _self = this;
_self.UserCompanies = ko.observableArray(
ko.utils.arrayMap(data.userCompanies, function (item) {
return new be.CompanyViewModel(item);
})
);
_self.SetSelectedManager = function (data, event) {
// remove all classes, then add the selected class to the selected element
$('.selectedApprover').removeClass('selectedApprover');
$('#' + data.ClientID()).addClass('selectedApprover');
// set UI elements
$('#selectedClientID').text(data.ClientID());
$('#selectedManagerName').text(data.ManagerName());
};
_self.GetSelected = function (data, event) {
console.log($('#selectedClientID').text());
};
};
be.CompanyViewModel = function (data) {
var _self = this;
ko.mapping.fromJS(data, {}, _self);
_self.Companies = ko.observableArray(
ko.utils.arrayMap(data.Companies, function (item) {
return new be.CompanyViewModel(item);
})
);
_self.Managers = ko.observableArray(
ko.utils.arrayMap(data.Managers, function (item) {
return new be.ManagerViewModel(item);
})
);
};
be.ManagerViewModel = function (data) {
var _self = this;
ko.mapping.fromJS(data, {}, _self);
_self.DefaultApproverClass = ko.observable('');
_self.SubordinateMgrs = ko.observableArray(
ko.utils.arrayMap(data.SubordinateMgrs, function (item) {
return new be.ManagerViewModel(item);
})
);
// Styles
_self.LoadStyleSelected = function() {
if (_self.IsDefaultApprover()) {
_self.DefaultApproverClass('selectedApprover');
$('#selectedManagerName').text(_self.ManagerName());
$('#selectedClientID').text(_self.ClientID());
}
};
// just call it the first time
_self.LoadStyleSelected();
};
的有所削減版本標記
<div id="CompanyTree">
<div class="selectedApproverHeader">
<h4 class="lighter smaller">Currently Selected Approver:
<br />
<span id="selectedManagerName"></span>,
ID: <span id="selectedClientID"></span>
</h4>
</div>
<div class="approver-list-contaier">
<ul data-bind="template: { name: 'companyElement', foreach: UserCompanies }"></ul>
</div>
<script id="companyElement" type="text/html">
<li class="companyList">
<h4 class="smaller" data-bind="text: CompanyName"></h4>
<ul class="managerList" data-bind="template: { name: 'managerElement', foreach: Managers }"></ul>
<ul data-bind="template: { name: 'companyElement', foreach: Companies }"></ul>
</li>
</script>
<script id="managerElement" type="text/html">
<li class="managerList">
<span data-bind="text: ManagerName, attr: { id: ClientID }, css: DefaultApproverClass, click: $root.SetSelectedManager"></span>
<ul data-bind="template: { name: 'managerElement', foreach: SubordinateMgrs }">
</ul>
</li>
</script>
<div>
<button data-bind="click:$root.GetSelected">Click Me</button>
</div>
</div>
任何原因你沒有使這個自定義的數據綁定? – noname
@Ben - 我在想我會遇到同樣的問題。如果您對我如何實現這一目標有所建議,我會很感激幫助。 –