简体   繁体   中英

Ember handlebars helper return value

I was trying to create a helper that would let me chain helpers together like:

{{ chain "striptags" "<p>asdf</p>" "truncate" 2 }}

But it seems like instead of returning the value after calling a helper in Ember, the last arg has a rendering buffer which gets manipulated by the ember helper. Is there a way to take a normal ember handlebars helper and return the value? My reference code:

/**
 * Allows some basic chaining of helpers.
 * {{ chain "helper1" arg1 arg2 "helper2" arg2 }}
 */
Ember.Handlebars.helper('chain', function() {
  var helperArgs = [];
  var helper;
  var that = this;
  var options = arguments[arguments.length - 1];
  $.each(arguments, function(i, arg) {
    if(Ember.Handlebars.helpers[arg]){
      if(helper){
        helperArgs.push(options);
        helperArgs = [helper.apply(that, helperArgs)];
      }
      helper = Ember.Handlebars.helpers[arg];
    }else{
      helperArgs.push(arg);
    }
  });
  return helper.apply(that, helperArgs);
});

This will sort of work:

Ember.Handlebars.helper('chain', function() {
    var that = this,
    helpers = [],
    current = null,
    options = arguments[arguments.length - 1];
    for (var i = 0; i < arguments.length - 1; i++) {
        var arg = arguments[i],
        helperFn = Ember.Handlebars.helpers[arg];
        if (helperFn) {
            current = {
                fn: helperFn,
                args: []
            };
            helpers.push(current);
        }
        else if (current) {
            current.args.push(arg);
        }
        else {
            throw new Error("Unknown helper: " + arg);
        }
    }
    var prevResult = null;
    $.each(helpers, function (index, helper) {
        var args = helper.args.concat(options),
            before = options.data.buffer.buffer;
        if (prevResult) {
            args.unshift(prevResult);
        }
        helper.fn.apply(that, args);
        var after = options.data.buffer.buffer;
        prevResult = after.slice(before.length).replace(/<\/?script[^>]*>/g, "");
        if (index < helpers.length - 1) {
            options.data.buffer.buffer = before;
        }
    });
});

JSBin .

The problem is, handlebars helpers don't really return a value. Instead, they write directly into the buffer provided through options argument. In the example above, I directly manipulate this buffer to extract product of one helper and insert it as the first argument of the next helper (stripping out ember metatags is just a bonus of WTF-ery).

As you can see, it works in this simple use case, but will probably break for anything more involved. Handlebars helpers just weren't designed to be used as functions.

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