how to avoid run code twice using ko property

2019-08-29 04:14发布

问题:

I am creating a list page where there are two datepicker and one table. The idea of the page it's load the page with some registration data using default parameters for the datepickers, after that the user will be able to choose what he want to see according to the datepicker filters. To run my app I have created two properties fromDate and toDate and i am using suscribe method in order to know when the dates are changed, so that when the dates are changed i should call to my services (or some filtering code). My issue with my page is that at the moment to load my page the control are seted by default from my own logic, so that my code that should call to my service is called twice (one in loadInitData and others in the suscriptions)

define(["require", "exports", 'services/logger',  '../../services/Assessment/datacontext'], function(require, exports, __logger__, __datacontext__) {
var logger = __logger__;

var datacontext = __datacontext__;    
exports.title = 'AssessmentListing';   
exports.fromDate = ko.observable(new Date('2012/12/12'));
exports.toDate = ko.observable(new Date('2012/12/12'));

function activate() {
   loadInitData();
}

exports.activate = activate;
function loadInitData() { 
   var focusDate = ko.observable(new Date('2013/07/06'));
   exports.fromDate(firstDayOfMonth(focusDate));
   exports.toDate(getLastDayOfMonth(focusDate));
   // calls to services
} 

exports.toDate.subscribe(function (newValue) {
   /*THIS CODE SHOULD BE EXECUTED JUST WHEN THE USER CHANGE THE DATE FROM THE CONTROL*/
   alert("new selection :");
});
exports.fromDate.subscribe(function (newValue) {
   /*THIS CODE SHOULD BE EXECUTED JUST WHEN THE USER CHANGE THE DATE FROM THE CONTROL*/
   alert("new selection");
});

function getLastDayOfMonth(focusDate) {
  var d = new Date(Date.apply(null, focusDate));
  d.setMonth(d.getMonth() + 1);
  d.setDate(0);
  return d;
}

function firstDayOfMonth(focusDate) {
   var d = new Date(Date.apply(null, arguments));
   d.setDate(1);
   return d;
}

function viewAttached() {
}
exports.viewAttached = viewAttached;
})

Try add a new boolean property to say loading(true) at the begining of loadInitData and loading(false) and the end of loadInitData. This work's fine. but still the suscription code is called more than one time.

回答1:

Probably a simple way to solve this is to delay setting up the subscriptions until your view model is initialized:

function activate() {
   loadInitData();

    exports.toDate.subscribe(function (newValue) {
       /*THIS CODE SHOULD BE EXECUTED JUST WHEN THE USER CHANGE THE DATE FROM THE CONTROL*/
       alert("new selection :");
    });
    exports.fromDate.subscribe(function (newValue) {
       /*THIS CODE SHOULD BE EXECUTED JUST WHEN THE USER CHANGE THE DATE FROM THE CONTROL*/
       alert("new selection");
    });
}