Ember.js:用一个视图替换简单的linkTo helper [英] Ember.js: replacing simple linkTo helper with a view
问题描述
linkTo
)转换为视图。问题是,我不知道如何将一个转换为另一个,并保持链接不变。 我该如何进行此转换?以下是我现在的代码:
< script type =text / x-handlebarsdata-template-name = accountItem>
{{#each account in controller}}
{{#linkToaccountaccount}}
< img {{bindAttr src =account.icon}} />
{{/ linkTo}}
{{/ each}}
< / script>
这里是我将要有的代码:
< script type =text / x-handlebarsdata-template-name =accountItem>
{{#控制器中的#each帐户}}
{{#viewSocial.AccountButtonView}}
< img {{bindAttr src =account.icon}} />
{{/ view}}
{{/ each}}
< / script>
Social.AccountButtonView = Ember.View.extend({
tagName:'a',
classNames:['item-account'],
click:function (){
// do something
}
});
我会假设我将构建在View中的点击处理程序的顶部,但是'不知道如何传递对被迭代的项目的引用,以及如何在视图中引用正确的路线。
请帮助?
更新1
第一个版本呈现一个值为的href属性#/ accounts / 4
根据我设置的路由器:
Social.Router.map (function(){
this.resource('accounts',function(){
this.resource('account',{path:':account_id'});
});
});
当我将当前代码转换为视图时,我如何模拟linkTo提供的功能? / p>
您可以在您的手柄模板中定义帐户
的属性绑定。
此绑定如下:
< script type =text / x-handlebars>
< h1> App< / h1>
{{#each item in controller}}
{{#viewview.AccountView accountBinding =item}}
< a {{bindAttr href =view.account.url }} target =_ blank>
{{view.account.name}}
< / a>
{{/ view}}
{{/ each}}
< / script>
请注意,我添加了 accountBinding
,所以一般规则是 propertyName
和绑定
作为后缀。请记住,当您向视图添加属性时,您将无法直接访问该属性,而您将不得不使用 view.propertyName
访问它,如上所示。
请记住,使用 {{ view}}
helper:
window.App = Em.Application.create();
/ pre>
App.AccountView = Em.View.extend(); //这必须存在
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'}];
}
})
工作小提琴: http:// jsfiddle。 net / schawaska / PFxHx /
响应更新1 :
我发现自己在类似的情况,最终创建一个子视图来模仿{{linkTo}}
帮助器。我真的不知道/认为这是最好的实现。
您可以在此处查看我以前的代码: http://jsfiddle.net/schawaska/SqhJB/
当时我在
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(),
IsAct ive:function(){
return this.get('item.routeName')=== this.get('parentView.selectedRouteName');
} .property('item','parentView.selectedRouteName')
})
})
});
,我的Handlebars如下所示:
< script type =text / x-handlebarsdata-template-name =menu-item>
< a {{action gotoRoute item on =clicktarget =view.parentView}}>
{{item.displayText}}
< / a>
< / script>
< script type =text / x-handlebarsdata-template-name =navbar>
< ul class =left>
{{#each item in controller}}
{{view view.MenuItemView itemBinding =item}}
{{/ each}}
< / ul>
< / script>
对不起,我不能给你一个更好的答案。这是我当时可以想出来的,从来没有触及过。就像我说的,我不认为这是处理它的方法。如果您愿意查看
{{linkTo}}
帮助源代码,您将看到一个模块化和优雅的实现,可以作为您自己实现的基础。我想你正在寻找的部分是href
属性,被定义如下: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));
})
...
});
所以我猜,从那里你可以理解它是如何工作和实现一些你自己的。让我知道这是否有帮助。
I've got an app with basic functionality built out. I'm not going through and adding additional features. In this case I need to convert a simple button, currently using
linkTo
, to a View. Problem is that I'm not sure how to convert one to the other and still keep the link intact.How do I do this conversion? Here's the code I have now:
<script type="text/x-handlebars" data-template-name="accountItem"> {{#each account in controller}} {{#linkTo "account" account}} <img {{bindAttr src="account.icon"}} /> {{/linkTo}} {{/each}} </script>
and here's the code I'm going to have:
<script type="text/x-handlebars" data-template-name="accountItem"> {{#each account in controller}} {{#view "Social.AccountButtonView"}} <img {{bindAttr src="account.icon"}} /> {{/view}} {{/each}} </script> Social.AccountButtonView = Ember.View.extend({ tagName: 'a', classNames: ['item-account'], click: function(){ // do something } });
I would assume that I'd be building on top of the click handler in the View, but I'm not sure how to pass the reference to item being iterated over, nor how to reference the correct route within the View.
Assistance please?
Update 1
The first version renders an href attribute with a value of
#/accounts/4
based on the Router I have set up:Social.Router.map(function() { this.resource('accounts', function(){ this.resource('account', { path: ':account_id'}); }); });
When I convert the current code to a view, how do I mimic the functionality that linkTo provides?
解决方案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 ispropertyName
andBinding
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 withview.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 thehref
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.
这篇关于Ember.js:用一个视图替换简单的linkTo helper的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!