简体   繁体   中英

How to make a prototype function “safe” to render from an ember.js template?

I have a simple patch on the native javascript date object to get me a formatted time using moment.js

(function() { 

  Date.prototype.utc = function() {
    return moment(this).format("MM/DD/YYYY h:mm a");
  }

})();

The problem is that when I invoke this from an ember.js template using a real date object like so

{{input id="foo" name="foo" value=start.utc}}

I get the "raw" output in my template instead of the new string I was expecting

function () { return moment(this).format("MM/DD/YYYY h:mm a"); }

Update

I realize you can create a computed property from the controller but I have this utc like formatting in a ton of templates (and non template code) so I'm looking for a solution that will let me reference the method with the least amount of boilerplate :)

Not sure if boundhelper functions would work.

Ember.Handlebars.registerBoundHelper('toUTC', function(value) {
  return moment(value).format("MM/DD/YYYY h:mm a");;
});

{{input id="foo" name="foo" value=toUTC start}}

I'd make a computed property in the model or controller that calls .utc() on the start date. The only kind of finnicky thing about this is that since you're binding the computed property to an input field I'm assuming you'll also need to convert from the provided utc format back to a regular date type. I'd do it something like this:

(function() { 

  var dateFormat = "MM/DD/YYYY h:mm a";

  Date.prototype.utc = function() {
    return moment(this).format(dateFormat);
  }

  String.prototype.utcToDate = function() {
    return moment(this, dateFormat).toDate();
  }

})();


{{input id="foo" name="foo" value=utcStart}}

Then the computed property, wherever you choose to place it, would be like:

utcStart: function(key, value) {
  if (arguments.length == 2) {
    this.set('start', value.utcToDate());
  }
  return this.get('start').utc();
}.property('start')

Update:

If you wanted the computed property logic to be reusable, then you could turn it into a computed property macro, like this blog post talks about. In this case, you could do something like:

App.computed.utcDate = function(dateFieldName) {
  return Ember.computed(dateFieldName, function(key, value) {
    if (arguments.length == 2) {
      this.set(dateFieldName, value.utcToDate());
    }
    return this.get(dateFieldName).utc();
  });
};

Then, in your controller/model, you can use it like:

utcStart: App.computed.utcDate('start')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM