Ember.js: replacing simple linkTo helper with a view

为君一笑 提交于 2019-12-04 16:50:11

You can define a property binding for account in your handlebars template. This binding works like this:

<script type="text/x-handlebars">
    <h1>App</h1> 
    {{#each item in controller}}
        {{#view App.AccountView accountBinding="item"}}
            <a {{bindAttr href="view.account.url"}} target="_blank">
                {{view.account.name}}
            </a>
        {{/view}}
    {{/each}}
</script>

Note that I added accountBinding, so the general rule is propertyName and Binding as a suffix. And remember that when you add a property to a view, you will not be able to access it directly, instead you will have to access it with view.propertyName as shown above.

Just keep in mind that you must have a View class when using the {{view}} helper:

window.App = Em.Application.create();
App.AccountView = Em.View.extend(); // this must exist
App.ApplicationRoute = Em.Route.extend({
    model: function() {
        return [
            {id: 1, name: 'Ember.js', url: 'http://emberjs.com'}, 
            {id: 2, name: 'Toronto Ember.js', url: 'http://torontoemberjs.com'}, 
            {id: 3, name: 'JS Fiddle', url: 'http://jsfiddle.com'}];    
    }
})

Working fiddle: http://jsfiddle.net/schawaska/PFxHx/

In Response to Update 1:

I found myself in a similar scenario, and ended up creating a child view to mimic the {{linkTo}} helper. I don't really know/think it's the best implementation tho. You can see my previous code here: http://jsfiddle.net/schawaska/SqhJB/

At that time I had created a child view within the ApplicationView:

App.ApplicationView = Em.View.extend({
  templateName: 'application',
  NavbarView: Em.View.extend({
    init: function() {
      this._super();
      this.set('controller', this.get('parentView.controller').controllerFor('navbar'))
    },
    selectedRouteName: 'home',
    gotoRoute: function(e) {
      this.set('selectedRouteName', e.routeName);
      this.get('controller.target.router').transitionTo(e.routePath);
    },
    templateName: 'navbar',
    MenuItemView: Em.View.extend({
      templateName:'menu-item',
      tagName: 'li',
      classNameBindings: 'IsActive:active'.w(),
      IsActive: function() {
        return this.get('item.routeName') === this.get('parentView.selectedRouteName');
      }.property('item', 'parentView.selectedRouteName')
    })
  })
});

and my Handlebars looks like this:

<script type="text/x-handlebars" data-template-name="menu-item">
  <a {{action gotoRoute item on="click" target="view.parentView"}}>
  {{item.displayText}}
  </a>
</script>

<script type="text/x-handlebars" data-template-name="navbar">
  <ul class="left">
    {{#each item in controller}}
      {{view view.MenuItemView itemBinding="item"}}
    {{/each}}
  </ul>
</script>

I'm sorry I can't give you a better answer. This is what I could come up with at the time and haven't touched it ever since. Like I said, I don't think this is the way to handle it. If you are willing to take a look into the {{linkTo}} helper source code, you'll see a modular and elegant implementation that could be the base of your own implementation. I guess the part you're looking for is the href property which is being defined like so:

var LinkView = Em.View.extend({
...
    attributeBindings: ['href', 'title'],   
    ... 
    href: Ember.computed(function() {
      var router = this.get('router');
      return router.generate.apply(router, args(this, router));
    })
...
});

So I guess, from there you can understand how it works and implement something on your own. Let me know if that helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!