在Moment.js对象上更改事件触发 [英] Change event triggering on momentjs object

查看:140
本文介绍了在Moment.js对象上更改事件触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的一个项目,我正在侦听模型对象的属性更改,并在其属性更改时调用视图方法.

For one of my projects, i'm listening on attribute changes on a model object and calling view methods if its attributes change.

问题是我的模型的属性之一是momentjs日期对象.

Problem is one of the attribute of my model is a momentjs date object.

我研究了主干源,似乎它使用下划线方法_.isEqual()触发了setter中的更改.

I've looked into backbone source and it seems it triggers changes in the setter using underscore method _.isEqual().

在阅读下划线文档之后,isEqual对这两个对象进行了深入的比较.

After reading underscore documentation, isEqual does a deep comparison of both objects.

看起来不错,但是momentjs对象包含初始格式设置信息,即使日期的实际值具有相同的含义,如果它来自不同的地方,它的格式也可能不同,因此,通过下划线深度比较可将其视为不相等.

Seems alright but momentjs object contains the initial formatting informations and even if the actual value of the date has the same meaning, if it comes from different place, it might be formatted differently and hence, be considered not equal by underscore deep comparison.

// initialize model
var today = moment().startOf('day');

var model = new Backbone.Model({
    start: today
});

// change event
model.on('change', function(e){
    // if property start has changed
    if(e.changed.hasOwnProperty('start')){
        // log it
        console.log('date changed');   
    }
});


// simulates input from user
var userInput = moment().startOf('day').format('DD/MM/YYYY');
model.set({
    // it's the same day as today and it shouldn't trigger a change !
    start: moment(userInput,'DD/MM/YYYY')
});

我应该怎么做?

  • 在我的模型中存储unix时间戳而不是momentjs对象?这也意味着重构我的整个代码...
  • 当它是momentjs对象时,找到一种替代" isEqual的方法?但是我宁愿不修改下划线,但是修改momentjs似乎没问题.
  • Store unix timestamp instead of momentjs object inside my model ? Which also means refactoring my whole code...
  • Find a way to "override" isEqual when it's a momentjs object ? But i would rather not modify underscore, modifying momentjs seems ok though.

推荐答案

最好的选择可能是重写model.set方法以对某些属性执行自定义的相等性检查.

You best bet is probably to override the model.set method to perform a custom equality check on certain attributes.

让我们创建EqualModels作为我们包含替代的基类:

Let's create EqualModels as our base class that holds the override:

var EqualModels = Backbone.Model.extend({
    set: function(key, val, options) {
        if (!this.equals)
            return Backbone.Model.prototype.set.apply(this, arguments);

        //lifted from Backbone source code
        var attrs, attr, dropped, fn;
        if (key == null) return this;

        // Handle both `"key", value` and `{key: value}` -style arguments.
        if (typeof key === 'object') {
            attrs = key;
            options = val;
        } else {
            (attrs = {})[key] = val;
        }
        options || (options = {});

        //determine which attributes have a custom equality check and apply it
        dropped = [];
        for (attr in attrs) {
            fn = this.equals[attr];
            if (_.isFunction(fn)) {
                if (fn(this.attributes[attr], attrs[attr]))
                    dropped.push(attr);
            }
        }

        //remove the attributes that are deemed equal
        attrs = _.omit(attrs, dropped);

        return Backbone.Model.prototype.set.call(this, attrs, options);
    }
});

目标是确定属性是否具有在this.equals中定义的相等性检查,将此函数应用于当前值和潜在值,如果认为值相等,则从设置的属性中删除该属性.

The goal is to determine if an attribute has an equality check defined in this.equals, apply this function on the current and potential values and remove the attribute from the set attributes if the values are deemed equal.

然后您可以将模型写为

var M = EqualModels.extend({
    equals: {
        start: function(v1, v2) {
            if (typeof(v1)!==typeof(v2)) return false;
            return v1.format('DD/MM/YYYY')===v2.format('DD/MM/YYYY');
        }
    }
});

此处仅当 DD/MM/YYYY 格式不同时才更新对象.还有一个演示 http://jsfiddle.net/Nwdf4/3/

Here the moment object is only updated when the DD/MM/YYYY formats are different. And a demo http://jsfiddle.net/Nwdf4/3/

这篇关于在Moment.js对象上更改事件触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆