在我的模型的activate()类中,我想要评估模型的布尔属性this.isExpanded,并在绑定之前将适当的类应用于我的视图(展开/折叠)。
function (system, app, ko) {
"use strict";
var SomeSection = contentControl.extend({
init: function () {
this.myBase();
this.app = app;
this.categories = ko.observableArray();
this.isExpanded = ko.observable(false);
},
activate: activate,
getData: getData,
initializeView: initializeView,
attached: attached,
validate: validate,
getView: getView,
expandAll: expandAll,
collapseAll: collapseAll
});
return SomeSection;
function activate() {
if (this.isExpanded) {
this.expandAll();
} else {
this.collapseAll();
}
}
function collapseAll() {
var that = this;
for (var i = 0; i < that.categories().length; i++) {
$('#' + that.categories()[i].name.replace(/[^a-zA-Z0-9]/g, '_')).removeClass('expand');
$('#' + that.categories()[i].name.replace(/[^a-zA-Z0-9]/g, '_')).addClass('collapse');
$("[data-toggle^='collapse']").addClass('collapsed');
}
}
}
但是,在绑定之前并不总是应用类。我应该从activate()
返回一个保证collapseAll()
在完成作曲之前已经运行的承诺吗?如果是这样,有人可以帮助说明这会是什么样子吗?
答案 0 :(得分:0)
我只能想到一种延迟视图组合的方法,并且可以使用durandal的getView钩子动态切换视图。我过去的方式是创建一个observable来跟踪激活码完成,然后使用该observable触发我的视图从虚拟加载视图切换到真实&#39;真实&#39 ;图。
前:
getView = ko.computed(function(){
return this.activateCompleted() ? 'MyView' : 'Loading'
})
function activate() {
if (this.isExpanded) {
this.expandAll();
} else {
this.collapseAll();
}
this.activateCompleted(true);
}
答案 1 :(得分:0)
您需要了解的是,您无法使用activate方法直接修改视图。这是因为第一次调用activate时不会组成视图。 请参阅Durandal生命周期文档:http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks.html
因此,如果您想在viewmodel中使用JQuery来控制视图,则只能在激活和附加回调运行后调用它。 (我的观点是Durandal缺少一个生命周期事件,当连接和激活都已运行时应该运行)。当然,当这两个方法都已运行时,你可以通过将observable设置为true来实现这一点。
但是在您的情况下,最简单和最自然的方法是使用绑定处理程序来控制视图中的可折叠类。在这种情况下,您可以从viewmodel中省略collapseAll()和expandAll()函数。 请参阅:http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html,当然还有像Roy J所指出的标准CSS绑定:http://knockoutjs.com/documentation/css-binding.html。
如果要在视图和视图模型之间保持真正的关注点分离,则应避免在viewmodel类中使用JQuery进行DOM操作。