Javascript durandaljs或knockoutjs中的自动调用函数

Javascript durandaljs或knockoutjs中的自动调用函数,javascript,knockout.js,momentjs,durandal-2.0,Javascript,Knockout.js,Momentjs,Durandal 2.0,我有一个应用程序,它使用MomentJS插件显示活动的相对时间。时间会自动刷新,并与当前时间和显示内容进行比较(如facebook新闻提要)。这个应用程序以前是用angularjs编写的,我在这里用以下代码构建了这个功能: JS: filter('convertSeconds', function() { return function(seconds) { if( typeof(seconds) == 'undefined' ) return;

我有一个应用程序,它使用MomentJS插件显示活动的相对时间。时间会自动刷新,并与当前时间和显示内容进行比较(如facebook新闻提要)。这个应用程序以前是用angularjs编写的,我在这里用以下代码构建了这个功能:
JS:

filter('convertSeconds', function() {
        return function(seconds) {
            if( typeof(seconds) == 'undefined' ) return;
            // units is a string with possible values of y, M, w, d, h, m, s, ms
            var duration = moment.utc().subtract(seconds, 'seconds'), format = "";

            if( duration.day() > 0 ) { format += "DD [days] "; }

            if(duration.hour() > 0){ format += "H [hours] "; }

            if(duration.minute() > 0){ format += "m [minutes] "; }

            format += " s [seconds]";

            return duration.fromNow(true);
        }
    }).
HTML:

<div class="time-spent">
   <i class="fa fa-clock-o mrs fa-2"></i>
   {{me.current.activity.time_spent|convertSeconds}}
</div>

{{me.current.activity.time}
angularjs过滤器每秒自动调用一次,因此时间被刷新,我不必处理这些

现在,应用程序正在被重写,js框架从angularjs转移到durandaljs(根据客户要求),我不知道如何使用durandaljs实现同样的效果。

durandal中的视图有一个javascript计时器,因此您可以使用事件启动(当视图被激活时)和停止(当视图被停用时)javascript计时器。在模型中添加一个名为time_Wasted_trigger的ko可观测值。添加另一个ko computed observable,名为time_Wasted_formatted,它执行所有力矩计算并返回最终结果,但在顶部,以某种方式引用time_Wasted_触发器。在您的视图中,绑定到time\u-spend\u-formatted属性,而不是time\u-spend属性。在激活事件中,启动一个计时器,每秒更新触发器花费的时间。在停用事件中,取消此计时器。更新触发器花费的时间的值将导致计算的可观测值发生更改,并在视图上更新

JS:

HTML:



所以你基本上需要一个相对的计时器,对吗

我们需要有人告诉我们现在是什么时间

//clock.js    
define(function (require) {
    var
        events = require('durandal/events'),
        moment = require('moment'),
        clock = {};

    events.includeIn(clock);

    setInterval(function () {
        clock.trigger('time:changed', moment());
    }, 1000);

    return clock;
});
这里是如何使用时钟事件的相对计时器

//timer.js
define(function (require) {
    var
        ko = require('knockout'),
        moment = require('moment'),
        startTime = ko.observable(null),
        relativeTime = ko.observable(),

        start = function () {
            startTime(moment());
        },
        stop = function () {
            startTime(null);
        },
        clock = require('clock');

    clock.on('time:changed').then(function (time) {
        startTime() && relativeTime(moment.duration(time, startTime()).humanize());
    });

    return {
        relativeTime: relativeTime, //use data-bind="text: relativeTime"
        start: start,
        stop: stop
    }

});

Angular应用程序变成了durandal应用程序,这很有趣。
Activity
本身能成为一个视图吗?你在一篇评论中提到了“一系列活动”。活动仅仅是具有一些属性的对象文字,还是更正式的东西?这个问题有点围绕着建筑。我们是在构建一个通用的相对计时器,还是专门构建一个活动相对计时器?此外,在开发该模块时,您可能需要考虑全局计时器方法。请看这个问题。应用程序的目的是跟踪不同人员在活动上花费的时间,因此我有一个活动列表,每个活动都有其属性。我特别需要一个活动相关计时器,因为用户也可以暂停和恢复时间。我有一个正在运行的活动数组,所以我必须更新数组中每个索引的time_-speed属性。我如何才能做到这一点。我是durandal的新手。然后你可以将timer.js设为工厂,并为数组中的每个项目创建一个实例。此视图将泄漏。您需要添加一个
分离的
处理程序,它也是视图生命周期的一部分,并带有以下行:
vm.time\u-speed\u-formatted.dispose()
。除非您使用新的
pureComputed
,否则如果确实可以使用它,您必须处理您的计算。@EricTaylor没有意识到这一点,所以如果这不是一个单例(而不是返回vm,而是返回一个用于创建vm对象的函数),我还需要进行处理吗?在非单例情况下更是如此。
//clock.js    
define(function (require) {
    var
        events = require('durandal/events'),
        moment = require('moment'),
        clock = {};

    events.includeIn(clock);

    setInterval(function () {
        clock.trigger('time:changed', moment());
    }, 1000);

    return clock;
});
//timer.js
define(function (require) {
    var
        ko = require('knockout'),
        moment = require('moment'),
        startTime = ko.observable(null),
        relativeTime = ko.observable(),

        start = function () {
            startTime(moment());
        },
        stop = function () {
            startTime(null);
        },
        clock = require('clock');

    clock.on('time:changed').then(function (time) {
        startTime() && relativeTime(moment.duration(time, startTime()).humanize());
    });

    return {
        relativeTime: relativeTime, //use data-bind="text: relativeTime"
        start: start,
        stop: stop
    }

});