我怎么知道每个循环中车把中的哪个项目触发了我的 Ember 控制器中的功能?
How can I know which item in a handlebars each loop triggered a function in my Ember controller?
我是 Ember 的新手,我正在尝试设置文件夹列表。当您单击文件夹旁边的图标时,它将加载(即 find('folder', folder_id) )子文件夹。如果顶级文件夹有 16 个子文件夹,我试图在这 16 个文件夹完成加载时设置 属性 - 因此如果其中一个子文件夹的模型已完成加载,我想要在其他 15 个文件夹仍在检索和序列化时对其设置 属性。
在我的文件夹模型中:
import DS from 'ember-data';
export default DS.Model.extend({
files: DS.hasMany('file'),
children: DS.hasMany('folder', { inverse: 'parent', async: true }),
parent: DS.belongsTo('folder', {inverse: 'children'}),
name : DS.attr('string'),
nodeId : DS.attr('string'),
classId : DS.attr('string'),
parentId: DS.attr('string'),
contents: DS.attr(),
isVisible: DS.attr('boolean'),
childName: DS.attr('string')
});
在我的 template/view:
{{#each child in children}}
{{#if child.isLoading}}
Loading -->
{{else}}
{{setChildProperty}}
{{/if}}
{{/each}}
在我的控制器中:
import Ember from 'ember';
export default Ember.Controller.extend({
children: function() {
var model = this.get('model');
var children = model.get('children');
return children;
}.property(),
setChildProperty: function(){
// how can I know, here in the controller, what the index is for
// the child that triggered this function, so that I can set a
// property on it without getting some type of
// 'didSetProperty / root.state.loading' error.
// The code below will cause errors because not all of the
// children have finished loading:
// var model = this.get('model');
// var self = this;
// var children = model.get('children');
// var contents = model.get('contents');
//
// children.forEach(function(item, index){
// var folderName = contents[index].folder;
// item.set('name',folderName);
// });
}.property('children.@each.isLoading'),
});
我的Ember-CLI版本是0.1.15
如有任何帮助,我们将不胜感激。
更新
关于 mpowered 的解决方案,真正的问题是我的文件夹模型的性质,因为文件夹模型没有名称 属性,而是有一个子名称列表。由于当用户单击子文件夹时会异步检索子关系,因此我需要从另一个数组(内容数组)中获取子文件夹名称,该数组具有相同的索引。所以使用 mpowered 的解决方案我的问题是这样的:
foldr: {{folder.id}}<br>
{{#each child in folder.children}}
{{#view 'toggle-list'}}
<i {{bind-attr id="child.id"}} class="fa fa-caret-right"></i>
{{/view}}
Index: {{_view.contentIndex}}
<!-- I need to be able to echo the above index in the
folder.contents array to get the child name.
-->
<!-- these work when uncommented, but I need a dynamic solution
name: {{folder.contents.[1].folder}}
name: {{folder.contents.1.folder}}
-->
<!-- None of these work:
name:{{!folder.contents.[_view.contentIndex].folder}}
name:{{!folder.contents.index.folder}}
name:{{!folder.contents.[index].folder}}
name:{{!folder.contents.{{!_view.contentIndex}}.folder}}
-->
Child:{{child.id}}..
<br>
<div {{bind-attr id="child.childName"}} class="folder-child hidden">
{{#if child.isVisible}}
isVisible is true<br>
{{folder-tree-component folder=child}}
{{/if}}
</div>
{{/each}}
我还应该注意,我使用的是 PODS 结构,我无法控制从服务器获得的 JSON 响应来填充我的模型(Ember 除外当然是序列化器)。
有很多事情与此有关。
首先,属性不是动作。当您获得 属性 时,您永远不想更改对象的状态,除非您有非常非常好的理由这样做,或者如果您正在实施 getter/setter 模式。删除 setChildProperty
,因为那都是不好的。在模板中,您应该只显示 属性,而不是 "do" 任何内容。
其次,这可能应该创建为一个组件,因为听起来您这里的递归结构很适合可重用的组件。类似于 folder-tree-component.hbs
:
{{folder.name}}
{{#each child in folder.children}}
{{folder-tree-component folder=child}}
{{/each}}
并且在您的主要路线中:
{{folder-tree-component folder=model}}
// Or, alternatively
{{#each child in model.children}}
{{folder-tree-component folder=child}}
{{/each}}
如果我理解正确的话,您需要在模型上计算 属性,而不是在模型(或 controller/component)完成加载后 "set" 某些东西。当 属性 被请求时,它将计算值并缓存它以防您再次请求它。在您的模型上:
name: function() {
// something with this.get('contents')
}.property('contents', 'otherDependency') // <- These will tell Ember to recompute the property when changed
在尝试解决这个问题之前,我会更多地了解 ember 基础知识,关于 Ember 如何滴答,有一些非常简单但至关重要的事情需要学习,而文件树不是最简单的实施开始。
我是 Ember 的新手,我正在尝试设置文件夹列表。当您单击文件夹旁边的图标时,它将加载(即 find('folder', folder_id) )子文件夹。如果顶级文件夹有 16 个子文件夹,我试图在这 16 个文件夹完成加载时设置 属性 - 因此如果其中一个子文件夹的模型已完成加载,我想要在其他 15 个文件夹仍在检索和序列化时对其设置 属性。
在我的文件夹模型中:
import DS from 'ember-data';
export default DS.Model.extend({
files: DS.hasMany('file'),
children: DS.hasMany('folder', { inverse: 'parent', async: true }),
parent: DS.belongsTo('folder', {inverse: 'children'}),
name : DS.attr('string'),
nodeId : DS.attr('string'),
classId : DS.attr('string'),
parentId: DS.attr('string'),
contents: DS.attr(),
isVisible: DS.attr('boolean'),
childName: DS.attr('string')
});
在我的 template/view:
{{#each child in children}}
{{#if child.isLoading}}
Loading -->
{{else}}
{{setChildProperty}}
{{/if}}
{{/each}}
在我的控制器中:
import Ember from 'ember';
export default Ember.Controller.extend({
children: function() {
var model = this.get('model');
var children = model.get('children');
return children;
}.property(),
setChildProperty: function(){
// how can I know, here in the controller, what the index is for
// the child that triggered this function, so that I can set a
// property on it without getting some type of
// 'didSetProperty / root.state.loading' error.
// The code below will cause errors because not all of the
// children have finished loading:
// var model = this.get('model');
// var self = this;
// var children = model.get('children');
// var contents = model.get('contents');
//
// children.forEach(function(item, index){
// var folderName = contents[index].folder;
// item.set('name',folderName);
// });
}.property('children.@each.isLoading'),
});
我的Ember-CLI版本是0.1.15
如有任何帮助,我们将不胜感激。
更新
关于 mpowered 的解决方案,真正的问题是我的文件夹模型的性质,因为文件夹模型没有名称 属性,而是有一个子名称列表。由于当用户单击子文件夹时会异步检索子关系,因此我需要从另一个数组(内容数组)中获取子文件夹名称,该数组具有相同的索引。所以使用 mpowered 的解决方案我的问题是这样的:
foldr: {{folder.id}}<br>
{{#each child in folder.children}}
{{#view 'toggle-list'}}
<i {{bind-attr id="child.id"}} class="fa fa-caret-right"></i>
{{/view}}
Index: {{_view.contentIndex}}
<!-- I need to be able to echo the above index in the
folder.contents array to get the child name.
-->
<!-- these work when uncommented, but I need a dynamic solution
name: {{folder.contents.[1].folder}}
name: {{folder.contents.1.folder}}
-->
<!-- None of these work:
name:{{!folder.contents.[_view.contentIndex].folder}}
name:{{!folder.contents.index.folder}}
name:{{!folder.contents.[index].folder}}
name:{{!folder.contents.{{!_view.contentIndex}}.folder}}
-->
Child:{{child.id}}..
<br>
<div {{bind-attr id="child.childName"}} class="folder-child hidden">
{{#if child.isVisible}}
isVisible is true<br>
{{folder-tree-component folder=child}}
{{/if}}
</div>
{{/each}}
我还应该注意,我使用的是 PODS 结构,我无法控制从服务器获得的 JSON 响应来填充我的模型(Ember 除外当然是序列化器)。
有很多事情与此有关。
首先,属性不是动作。当您获得 属性 时,您永远不想更改对象的状态,除非您有非常非常好的理由这样做,或者如果您正在实施 getter/setter 模式。删除 setChildProperty
,因为那都是不好的。在模板中,您应该只显示 属性,而不是 "do" 任何内容。
其次,这可能应该创建为一个组件,因为听起来您这里的递归结构很适合可重用的组件。类似于 folder-tree-component.hbs
:
{{folder.name}}
{{#each child in folder.children}}
{{folder-tree-component folder=child}}
{{/each}}
并且在您的主要路线中:
{{folder-tree-component folder=model}}
// Or, alternatively
{{#each child in model.children}}
{{folder-tree-component folder=child}}
{{/each}}
如果我理解正确的话,您需要在模型上计算 属性,而不是在模型(或 controller/component)完成加载后 "set" 某些东西。当 属性 被请求时,它将计算值并缓存它以防您再次请求它。在您的模型上:
name: function() {
// something with this.get('contents')
}.property('contents', 'otherDependency') // <- These will tell Ember to recompute the property when changed
在尝试解决这个问题之前,我会更多地了解 ember 基础知识,关于 Ember 如何滴答,有一些非常简单但至关重要的事情需要学习,而文件树不是最简单的实施开始。