2

使用 durandal 和淘汰赛我在订阅属性方面遇到了一些问题。基本上在我的 viewAttached 方法中,我订阅了一些可观察的属性,当我加载我的视图时,这些属性在第一次工作时效果很好。在第二次加载视图时,由于订阅中的代码被执行(我不想要的东西),我遇到了一些问题。代码是这样的:

export var viewAttached = function (view) {


toDate.subscribe(function (newValue) {      
    isLoading(true);
    return datacontext.getData(newValue).then(function () {
        isLoading(false);
    });
});

fromDate.subscribe(function (newValue) {       
    isLoading(true);
    return datacontext.getData(newValue).then(function () {
        isLoading(false);
    });
});
}

订阅中的代码目前正在执行以第二次加载我的视图,出了什么问题。我想知道是否可以删除对此属性的订阅以卸载我的视图。那可能吗?有可能知道何时卸载视图?任何帮助都将不胜感激。

更新: 我尝试删除激活功能中的订阅(请参阅 durandal 文档),但订阅代码还在那里。

export function activate() {      
   //remove suscriptions
    toDate.subscribe(function (newValue) {
     //do nothing
    });

    fromDate.subscribe(function (newValue) {
     //do nothing
    });   
}

更新: fromDate 和 ToDate 被声明为(我正在使用打字稿)

export var fromDate = <any>ko.observable();
export var toDate = <any>ko.observable();

fromDate 和 toDate 并在 activate 方法上默认设置:

function loadInitData() {   
   var focusDate = ko.observable(selectedDate);
   fromDate(firstDayOfMonth(focusDate));
   toDate(getLastDayOfMonth(focusDate));
   loadFilterLookups();
   loadRegistrations();   
}


export function activate() {      
   loadInitData();
}
4

2 回答 2

3

基本解决方案

您问如何取消订阅已订阅 KnockoutJS 的内容。

Knockout 可观察订阅为此公开了一个.dispose()函数。

订阅时:

var subscription = toDate.subscribe(function (newValue) {
 //do nothing
});
 

清理:

subscription.dispose();

如果您希望对多个订阅进行此操作,您可能需要考虑将它们推送到一个数组中,然后在所有订阅之后进行清理,例如

var subs = [];
function subSafe(observable,function){
    subs.push(observable.subscribe(function));
}
function unsubscribeAll(){
    subs.forEach(function(subscription){
        subscription.dispose();
    });
}

一个独立的例子。

假设我们有两个按钮和一个值,一个按钮会增加该值。我们有一个监听值变化的监听器,它有一个alert. 当我们单击第二个按钮时,订阅被删除。

HTML:

<button data-bind="click: $root.inc">Inc</button>
<button data-bind="click: $root.unsub">Remove subscription</button>

JavaScript:

var vm = {
    val:ko.observable(0),
    inc:function(){
        vm.val(vm.val()+1);
    },
};
vm.sub = vm.val.subscribe(function(newVal){
   alert("Increased to "+newVal); 
});
vm.unsub = function(){
    vm.sub.dispose();    
}
ko.applyBindings(vm);

这是一个简短的小提琴说明了这个过程

于 2013-07-15T21:04:33.307 回答
0

简单 - 将您的 ViewAttached 代码移动到您的 Activated 函数中 - 然后它只会在第一次加载 View 时加载。

于 2013-07-11T15:34:24.417 回答