1

Ember.LinkView,把手 {{linkTo}} 帮助器背后的视图类现在在 Ember 1.0 RC2 中是公共的。我想扩展它,这样我就可以创建一个自定义视图,而无需为链接添加额外的嵌套标签。

例如:

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 元素。

4

2 回答 2

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 源代码在这里阅读起来非常方便,但我不得不重写一个私有方法,所以我认为这不是很理想。这是实现。请记住,我试图控制 View 何时触发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

如果你想要两者兼得,你可以结合这两个方法和 extend Ember.LinkView,创建一个自定义的 Handlebars 助手,并使用自定义事件名称来表示你想要采取的行动。这样,就不需要覆盖Ember.LinkView和覆盖。_invoke

祝你好运!

于 2013-10-12T03:23:28.373 回答
2

LinkView 旨在通过帮助程序创建,该帮助程序传递(并为某些选项提供默认值)。

尝试确定您的自定义类是否存在时会发生错误 active。您需要执行以下操作之一

  • 使用 App.MyLinkView 时传递或提供预期的默认选项
  • 覆盖active函数并实现你需要的
  • 只需将选项传递给{{linkTo}}您想要的行为
  • 重新打开 Ember.LinkView 以提供您想要的应用程序范围的行为
于 2013-04-20T19:35:01.780 回答