简体   繁体   中英

Overloading “link-to” helper in ember.js

I'm trying to make a custom helper that does the same thing that link-to, except with a few more assumptions.

I'm trying to make this:

{{#my-link-to widget.href}}{{widget.title}}{{/my-link-to}}

It takes the route parameters only (widget.href), and the route is assumed to be 'root'. Here's how I'm implementing it:

Ember.Handlebars.registerHelper('my-link-to', function() {
  var args = [].slice.call(arguments);
  args.unshift('root'); // always use the 'root' route

  return Ember.Handlebars.helpers['link-to'].apply(this, args);
});

However, my resulting links turn out to be all pointing to /# and I get a This link-to is in an inactive loading state because at least one of its parameters presently has a null/undefined value, or the provided route name is invalid. error.

Doing {{#my-link-to 'root' widget.href}}{{widget.title}}{{/my-link-to}} and removing args.unshift('root') works as expected.

I have a fiddle demonstrating this here: http://jsfiddle.net/p2R9y/3/

I'm really new to Ember.js so let me know if I'm doing something blatantly wrong.

Each argument passed to a handlebars view helper have some additional informantion. So args.unshift('root'); isn't enough you need to say what "root" means: a binding a string literal etc. In your case is a string literal, because the expected usage is:

{{#my-link-to-works 'root' widget.href}}

You need to use STRING in the options hash types key

Ember.Handlebars.registerHelper('my-link-to-fails', function() {
  var args = [].slice.call(arguments),
      options = args[args.length-1]; // last argument is always the options hash

  args.unshift('root');
  // the types says what is the type of each argument, in that case we need STRING
  options.types.unshift('STRING');

  return Ember.Handlebars.helpers['link-to'].apply(this, args);
});

I updated your fiddle with this code please give a look http://jsfiddle.net/marciojunior/sR96j/

I think figured your problem.

1. You got your example mixed up

You are adding 'root' to the my-link-to-works helper:

{{#my-link-to-works 'root' widget.href}}

and doing the unshift on the my-link-to-fails helper. So actually both examples are different. One has two arguments (ex: 'root' and '/widget/foo') and the other only has one (ex: '/widget/foo').

2. Anyway, why does it work when the first argument is 'root'?

The link-to helper first argument must be a routeName . This helper can also receive a second argument supplying an explicit dynamic segment value which appends it's value to the resolved route. This was how your arguments were interpreted. If you check your example, the working links resolve to, for example, #//widget/foo . You may notice the two forward slashes there, which are a result of your resolved route #/ + your segment value /widget/foo .

3. Solution?

Use the link-to helper directly: {{link-to 'widget' 'widget.href'}} and remove the /widget/ part from your href strings or do something like this: http://jsfiddle.net/tqFJ3/4/

The helper: (this is the same as using link-to directly)

Ember.Handlebars.registerHelper('my-link-to-works', function() {
  // Do extra stuff here...
  return Ember.Handlebars.helpers['link-to'].apply(this, arguments);
});

Change your widgets href and leave only the dynamic segments:

App.IndexRoute = Ember.Route.extend({
    model : function() {
        return {
            widgets: [
              { href: 'foo' },
              { href: 'bar' },
              { href: 'baz' }
            ]
        };
    }
});

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