递归淘汰列表-不使用jQuery设置选定值
如果我试图更改元素的样式或可见性,我会后悔在淘汰视图模型中使用jQuery。所以我猜有更好的方法: 我有一些递归淘汰视图模型来显示公司的树状结构,这些公司中的经理,以及这些经理下的任何公司等等(因此递归性) 在递归创建这些对象时,如何从$root(ApproverViewModel)中设置子对象(ManagerViewModel)中的可观察对象?目前,我正在使用jQuery进行这项工作,并设置一个隐藏元素的值,但这似乎与KO的可观察模式背道而驰——这让我觉得有一种更好的方式,我只是不知道 在MangerViewModel中,我将在页面第一次加载时设置递归淘汰列表-不使用jQuery设置选定值,jquery,recursion,knockout.js,Jquery,Recursion,Knockout.js,如果我试图更改元素的样式或可见性,我会后悔在淘汰视图模型中使用jQuery。所以我猜有更好的方法: 我有一些递归淘汰视图模型来显示公司的树状结构,这些公司中的经理,以及这些经理下的任何公司等等(因此递归性) 在递归创建这些对象时,如何从$root(ApproverViewModel)中设置子对象(ManagerViewModel)中的可观察对象?目前,我正在使用jQuery进行这项工作,并设置一个隐藏元素的值,但这似乎与KO的可观察模式背道而驰——这让我觉得有一种更好的方式,我只是不知道 在Ma
\u self.DefaultApproverClass()
。然后,当用户选择一个不同的管理器时,我只是删除所有的类,找到新选择的元素的ID并对其应用CSS类
我猜有一种更好、更“击倒递归”的方法来实现这一点。有什么建议吗
下面是我的ViewModels()的精简版本
加价
<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>
当前选定的审批人:
,
身份证件:
点击我
删除所有jQuery代码,使用ko控制所有视图表示,查看更新的JSFIDER
为了处理复杂的数据,有一个init逻辑来查找初始默认管理器
be.ApproverViewModel = function (data) {
var _self = this;
_self.SelectedManager = ko.observable();
_self.UserCompanies = ko.observableArray(
ko.utils.arrayMap(data.userCompanies, function (item) {
return new be.CompanyViewModel(item);
}));
_self.GetSelected = function (data, event) {
if (_self.SelectedManager()) alert(_self.SelectedManager().ClientID());
};
// init default one
function find_default(companies) {
var default_manager;
ko.utils.arrayFirst(companies, function(c) {
var a_default = ko.utils.arrayFirst(c.Managers(), function(m) {
return m.IsDefaultApprover();
});
if (a_default) {
default_manager = a_default;
return true;
} else {
var deeper_default = find_default(c.Companies());
if (deeper_default) {
default_manager = deeper_default;
return true;
}
}
});
return default_manager;
}
_self.SelectedManager(find_default(_self.UserCompanies()));
};
顺便说一句,如果你愿意牺牲可读性,你可以简化find_default()。
你为什么不将其作为自定义数据绑定?@Ben-我想我也会遇到同样的问题。如果你对我如何做到这一点有什么建议,我将非常感谢你的帮助。太好了,谢谢你!我在玩弄一个递归循环,但没有弄明白。谢谢你提供这两个例子。
be.ApproverViewModel = function (data) {
var _self = this;
_self.SelectedManager = ko.observable();
_self.UserCompanies = ko.observableArray(
ko.utils.arrayMap(data.userCompanies, function (item) {
return new be.CompanyViewModel(item);
}));
_self.GetSelected = function (data, event) {
if (_self.SelectedManager()) alert(_self.SelectedManager().ClientID());
};
// init default one
function find_default(companies) {
var default_manager;
ko.utils.arrayFirst(companies, function(c) {
var a_default = ko.utils.arrayFirst(c.Managers(), function(m) {
return m.IsDefaultApprover();
});
if (a_default) {
default_manager = a_default;
return true;
} else {
var deeper_default = find_default(c.Companies());
if (deeper_default) {
default_manager = deeper_default;
return true;
}
}
});
return default_manager;
}
_self.SelectedManager(find_default(_self.UserCompanies()));
};
// init default one
function find_default(companies) {
var default_manager;
ko.utils.arrayFirst(companies, function(c) {
return default_manager = ko.utils.arrayFirst(c.Managers(), function(m) {
return m.IsDefaultApprover();
}) || find_default(c.Companies());
});
return default_manager;
}