2013-04-20 97 views
1

Ember.LinkView,车把后面的视图类{{linkTo}}辅助现已在灰烬1.0 RC2公众。我想扩展它,所以我可以创建一个自定义视图,而不需要为linkTo添加额外的嵌套标记。扩展灰烬LinkView

例如:

App.MyLinkView = Ember.LinkView.extend({ 
    namedRoute: 'another' 
}); 

然后

{{#view App.MyLinkView}}LinkView to another route{{/view}} 

通过源看起来有点没有多少运气,因为它经常引发错误。 下面是标准{{linkTo}}工作的jsfiddle,并且LinkView尝试注释掉了,所以它不会引发错误。

http://jsfiddle.net/HgmEy/1/


编辑:

这里是你为什么会想这样做一个更现实的例子: http://jsfiddle.net/HgmEy/3/

所需的功能正在这里使用常规查看,但使用LinkView将优先避免额外的dom元素。

回答

2

LinkView旨在被经由一个辅助,其通过(并提供默认值)的一些选项创建的。试图确定您的自定义类是active与否时出现

你的错误。你需要做以下

  • 通的一个或提供预期的默认选项使用App.MyLinkView
  • 覆盖的active功能时,并实现你所需要的
  • 只是通过选项{{linkTo}}为你想要的行为
  • 重新Ember.LinkView提供应用范围的行为你想要
+0

感谢Trek,仍然没有运气。我添加了一个更好的例子。我想知道是否可以通过使用tagName:'a'的常规视图来实现。事情是,我想利用路由的序列化方法来确定href。 – gdub 2013-04-20 22:24:45

+0

通过在linkTo帮助程序上使用templateName来实现它。 (http://jsfiddle.net/HgmEy/4/)适用于这种情况,但如果您想为视图类添加额外的功能,仍然有需要。 – gdub 2013-04-20 22:57:52

2

我需要做这个覆盖Ember.LinkView致电transitionTo,以便为转换之间的jQuery动画提供解决方案。在我看来,有几个可行的方法来覆盖LinkView。我成功的第二个是Trek的最后一个选择,而且更简单。这是方法#2:

方法2

{{#linkTo 'items' this eventName="myEvent"}} Link to {{title}} {{/linkTo}} 

现在重写应用范围LinkView:

Ember.LinkView.reopen({ 
    // this handler is still called on click, but 
    // if we specify eventName in our template, 
    // we can call that handler only when we need to, 
    // or not at all 
    click: function (e) { 
    var evtName = this.get('eventName'); 

    // transitionTo was already invoked by 
    // this._invoke() if evtName was `click` 
    if (evtName === 'click') return; 

    e.preventDefault(); 

    // do some stuff here 

    var args = [].slice.call(arguments); 
    this.trigger.apply(this, [evtName].concat(args)); 
    } 
}); 

方法#1

我来到第一种方法与延伸Ember.LinkView并创建一个习惯Handlebars帮手。 Ember的源代码在这里阅读非常方便,但我不得不重写一个私有方法,所以我不认为这是非常理想的。这是实现。请记住我试图控制时查看触发了transitionTo

{{#appLinkTo 'items' this}} Link to {{title}} {{/appLinkTo}} 

现在的代码吧!

App.LinkView = Ember.LinkView.extend({ 
    // always called after this.invoke(), 
    // which calls transitionTo 
    click: function (e) { 
    e.preventDefault(); 
    }, 

    // already bound to the click event by this.init(). 
    // our click handler above always gets called after this one 
    _invoke: function (event) { 
    // we need to simulate the old _invoke if we 
    // want to override its call to transitionTo 
    // 
    // https://github.com/emberjs/ember.js/blob/v1.0.0/packages/ember-routing/lib/helpers/link_to.js#L297 
    var isSimpleClick = Ember.ViewUtils.isSimpleClick; 
    if (!isSimpleClick(event)) { return true; } 
    event.preventDefault(); 
    if (this.bubbles === false) { event.stopPropagation(); } 
    if (this.get('_isDisabled')) { return false; } 

    if (this.get('loading')) { 
     Ember.Logger.warn("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."); 
     return false; 
    } 

    // now we can start messing around 
    var routeArgs = this.get('routeArgs'); 
    // routeArgs seems to have format ['routeName', models for dynamic segments] 
    this.set('routeArgs', ['group', routeArgs[1]]); 

    // if we use: 
    this.get('controller').send('someAction', routeArgs); 

    // the controller can do in its `someAction` handler: 
    // `this.transitionToRoute.apply(this, routeArgs);` 
    } 
}); 

// besides the naming, this is verbatim from the end of: 
// https://github.com/emberjs/ember.js/blob/v1.0.0/packages/ember-routing/lib/helpers/link_to.js 
Ember.Handlebars.registerHelper('app-link-to', function(name) { 
    var options = [].slice.call(arguments, -1)[0], 
     params = [].slice.call(arguments, 0, -1), 
     hash = options.hash; 

    hash.disabledBinding = hash.disabledWhen; 
    hash.parameters = { 
     context: this, 
     options: options, 
     params: params 
    }; 

    return Ember.Handlebars.helpers.view.call(this, App.LinkView, options); 
}); 

Ember.Handlebars.registerHelper('appLinkTo', Ember.Handlebars.helpers['app-link-to']); 

方法#3

如果你想两全其美,你可以结合这两种方法,并延长Ember.LinkView,创建自定义的把手帮手,并使用自定义事件名称,以表示该行动你想要拿。这样,覆盖Ember.LinkView,并覆盖_invoke是没有必要的。

祝你好运!