2013-10-04 242 views
1

這是應用程序的流程:訂閱事件都沒有退訂

的shell.js加載schoolyeardialog.js其中包含schoolyearwizard.js通過它加載創建或編輯按鈕schoolyearbrowser.js。

當我重複這些步驟多次:單擊創建/編輯按鈕,然後我做我的SchoolyearWizard多個 要求是:

$.when(service.editSchoolyear(schoolyearId)) 

的原因是,訂閱事件是不是在我看來,正確退訂。

我試圖在SchoolyearDialog.js文件退訂不同的方式。

無論是事件不火 - 當我做了subscription.off();在app.on(...) 之後或者它被取消訂閱了錯誤的位置。

我應該在哪裏正確退訂?

如果你們需要一個樣品回購作爲Visual Studio解決方案,我可以提供這一點,如果它可以幫助或者你看得很清楚,並立即錯誤?

我也考慮過退出2個事件創建/編輯時,SchoolyearDialog模塊是「卸載」,因爲那麼這兩個事件可以/不會退訂,不僅是創建或編輯訂閱,因爲它現在是當我單擊添加或編輯按鈕...我該怎麼做?

SHELL

define(['plugins/router', 'durandal/app', 'viewmodels/SchoolyearDialog', 'knockout'], function (router, app, schoolyearDialog, ko) { 

    self.schoolyearIsLoaded = ko.observable(false); 

    var saveTimeTableSubscription = app.on('savedTimeTable').then(function (options) { 
     // after coming the 2nd time here 
     if (!self.schoolyearIsLoaded()) { 
      router.map([{ route: 'lessonplanner', moduleId: 'viewmodels/lessonplanner', title: 'lesson planner', nav: true }, 
         { route: 'documentbrowser', moduleId: 'viewmodels/documentbrowser', title: 'document browser', nav: true }]) 
       .buildNavigationModel(); 

      self.schoolyearIsLoaded(true); 
     } 

     router.navigate("lessonplanner", true); 
    }); 


    return { 
     router: router, 
     activate: function() { 
      router.map([{ route: '', moduleId: 'viewmodels/SchoolyearDialog', nav: true, title: 'Schoolyearbrowser' } 
      ]).buildNavigationModel(); 
      return router.activate('SchoolyearDialog'); 

     } 
    }; 
}); 

SchoolyearDialog

define(['durandal/app', 'knockout', 'plugins/router', 'viewmodels/SchoolyearWizard'], 
    function (app, ko, router, wizard) { 

     var ctor = function() { 
      debugger; 
      var self = this; 
      self.createSubscribe = ko.observable(); 
      self.editSubscribe = ko.observable(); 

      self.activeScreen = ko.observable('viewmodels/SchoolyearBrowser'); // set the schoolyear browser as default module 

      var createWizardSubscription = app.on('createWizard').then(function() { 

       self.createSubscribe().off(); 
       self.createSubscribe(null); 

       self.activeScreen(new wizard('create')); 

      }, self); 
      self.createSubscribe(createWizardSubscription); 

      var editWizardSubscription = app.on('editWizard').then(function (schoolyearId) { 

       self.editSubscribe().off(); 
       self.editSubscribe(null); 

       self.activeScreen(new wizard('edit', schoolyearId)); 

      }, self); 
      self.editSubscribe(editWizardSubscription); 
     } 
     return ctor; 
    }); 

SchoolyearBrowser

define(['durandal/app', 'plugins/dialog', 'knockout', 'services/dataservice', 'plugins/router'], 
    function (app, dialog, ko, dataservice, router) { 
     var SchoolyearBrowser = function() { 

      var self = this; 
      self.schoolyears = ko.observableArray(); 

      $.when(dataservice.getSchoolyears()) 
      .done(function (schoolyearModels) { 
       self.schoolyears(schoolyearModels); 
      }); 

      self.create = function() { 
       app.trigger('createWizard'); 
      } 

      self.edit = function() { 
       app.trigger('editWizard', 1); 
      } 
     }; 

     return SchoolyearBrowser; 
    }); 

SchoolyearWizard

define(['durandal/activator', 'viewmodels/step1', 'viewmodels/step2', 'knockout', 'durandal/app', 'services/dataservice', 'viewmodels/CreateEditSchoolyearViewModel'], 
    function (activator, Step1, Step2, ko, app, service, CreateEditSchoolyearViewModel) { 

     var ctor = function (viewMode, schoolyearId) { 
      debugger; 
      // depending on the mode I could setup 2 different step modules for create and edit ? and the Wizard has one property called content 
      if (viewMode === 'edit') { 

       $.when(service.editSchoolyear(schoolyearId)) 
       .done(function (response) { 
        debugger; 
        self.viewModel(new CreateEditSchoolyearViewModel(response)); 
       }).fail(function (error) { 
        alert(error); 
       }); 
      } 
      else if (viewMode === 'create') { 

       $.when(service.createSchoolyear()) 
       .done(function (response) { 
        debugger; 
        self.viewModel(new CreateEditSchoolyearViewModel(response)); 
       }).fail(function (error) { 
        alert(error); 
       }); 
      } 

      var self = this; 
      var steps = [new Step1(viewMode), new Step2(viewMode)]; 
      var step = ko.observable(0); // Start with first step 
      self.activeStep = activator.create(); 
      var stepsLength = steps.length; 

      self.viewModel = ko.observable(); 

      this.hasPrevious = ko.computed(function() { 
       return step() > 0; 
      }); 

      self.caption = ko.observable(); 
      this.activeStep(steps[step()]); 

      this.hasNext = ko.computed(function() { 
       if ((step() === stepsLength - 1) && self.activeStep().isValid()) { 
        // save 
        self.caption('save'); 
        return true; 
       } else if ((step() < stepsLength - 1) && self.activeStep().isValid()) { 
        self.caption('next'); 
        return true; 
       } 
      }); 

      this.isLastStep = function() { 
       return step() === stepsLength - 1; 
      } 

      this.next = function() { 
       if (this.isLastStep()) { 

        var vm = this.activeStep(); //.viewModel; 

        $.when(service.saveCreateSchoolyear({ schoolyearId: 1 })).done(function() { 

         app.trigger('savedTimeTable', { isSuccess: true }); 
        }).fail(function (e) { 

         alert(e); 
        }); 

       } 
       else if (step() < stepsLength) { 
        step(step() + 1); 
        self.activeStep(steps[step()]); 
       } 
      } 

      this.previous = function() { 
       if (step() > 0) { 
        step(step() - 1); 
        self.activeStep(steps[step()]); 
       } 
      } 
     } 
     return ctor; 
    }); 
+0

這是一個有點冗長,難以遵循。究竟是什麼問題? –

+0

@MatthewJamesDavis看到我的解決方案;-)如果你完全讀了我的init問題,實際上所有的東西都說了。 – Elisabeth

回答

0

這極大地幫助了我:

activator.deactivate功能允許一個對象執行自定義停用邏輯「

SchoolyearDialog.js 

self.deactivate = function() { 
       self.createSubscribe().off(); 
       self.editSubscribe().off(); 
} 

當schoolyearDialog停用這兩個事件都退訂。單擊不確定按鈕創建/編輯。這對我來說是一個乾淨的解決方案:)

0

我同意你的解決方案,但我建議不要使用普通.off()沒有參數,因爲這將導致註銷應用程序中的所有事件。

而是傳遞事件名作爲參數傳遞給您的關閉方式:

self.createSubscribe().off('savedTimeTable');