2013-04-20 98 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是沒有必要的。

祝你好運!