【问题标题】:remove ko suscrptions in durandal?删除 durandal 中的 ko suscrptions?
【发布时间】:2013-07-11 15:31:45
【问题描述】:

使用 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();
}

【问题讨论】:

  • 在定义toDatefromDate 之后没有立即设置subscribe 是否有原因?
  • 原因是因为在我的激活方法中,我使用 fromDate 和 toDate 的默认值调用我的服务。所以我所做的是:1)使用默认值设置变量 2)调用我的服务 3)从 UI 中为我的过滤器中的期货更改添加订阅。查看这篇文章:stackoverflow.com/questions/17178632/…
  • 您能否展示您的 AMD 大纲,其中定义了 toDatefromDate 以及模块返回的是单例函数还是构造函数?如果使用单例,你的视图中是否打开了 cacheViews: true ?
  • 很遗憾我正在使用 TypeScript(我很遗憾地说,因为我更喜欢使用 pur js)。 typescript 如何将其代码转换为纯 js 的方式是创建一个名为 export 的依赖项。这样fromDate和toDate的声明就是:exports.fromDate = ko.observable(); export.toDate = ko.observable();
  • 遗憾的是我的 TypeScript 不够流利 ;-),所以如果你可以添加编译后的 JavaScript。我想看看定义 addDatefromDate 的 JS 以及它周围的 require define

标签: javascript knockout.js durandal


【解决方案1】:

基本解决方案

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

Knockout observable 订阅为此公开了一个 .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);

Here is a short fiddle illustrating the process

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 感谢反馈,viewAttached 方法的代码执行一次。问题是订阅中的代码每次都会执行(我可以认为属性持有或记住订阅)。我尝试做的一件事是用激活函数中的任何内容替换订阅函数(根据 durandal 文档,您知道激活函数是在附加视图功能之前执行的)。查看我的更新。
    • 您是否在每次加载时都运行的函数中设置了 fromDate 和 toDate 值?这是我看到这种情况发生的唯一方法 - 只有当值发生变化时,订阅才会受到影响。
    • 是的,我拥有它,但我对此无能为力。在调用 datacontext 之前,我必须设置一个默认过滤器。我想在这个订单上有我的代码。 0) 删除订阅(如果存在)。 1) 设置默认日期 2) 添加订阅。
    • 或者,有一个在激活时设置为 true 的变量,然后设置您的项目并检查您的订阅以查看该变量是否为 false。如果为真,则不运行订阅代码。然后,在调用 viewAttached 时将此变量设置为 false,以便订阅工作。
    • 不错的尝试,但不起作用。其他 js 库正在标记中设置值,因此订阅代码再次运行(在将 bool 设置为 false 之后)。所以我回到我原来的问题,如何删除订阅代码?我怎么能说 suscription=null?
    猜你喜欢
    • 2013-08-16
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-11-11
    • 2015-03-02
    • 2013-05-15
    • 2023-03-21
    相关资源
    最近更新 更多