我一直在努力学习Ember的基础知识,现在我已经遇到了一个问题,当谈到通过控制器中的动作改变模型中的数据时。
我发现的所有例子似乎都在使用一维装置。我使用的灯具如下所示:
App.ClassGroup = DS.Model.extend({
className: DS.attr('string'),
isActive: DS.attr('number'),
students: DS.hasMany('Students',{async:true}),
selected: DS.hasMany('Students',{async:true})
});
App.ClassGroup.FIXTURES = [
{
id: 123,
className: 'Class 1',
isActive: 1,
students: [11, 22, 33, 44, 55],
selected: [11, 22, 33, 44, 55]
},
{
id: 456,
className: 'Class 2',
isActive: 0,
students: [66, 77, 88, 99],
selected: [66, 88, 99]
},
{
id: 789,
className: 'Group 1',
isActive: 0,
students: [77, 22],
selected: []
}
];
App.Students = DS.Model.extend({
first: DS.attr('string'),
last: DS.attr('string'),
classes: DS.hasMany('ClassGroup')
});
App.Students.FIXTURES = [
{
id: 11,
first: 'Student',
last: 'One',
classes: [123]
},
{
id: 22,
first: 'Student',
last: 'Two',
classes: [123, 789]
},
{
id: 33,
first: 'Student',
last: 'Three',
classes: [123]
},
{
id: 44,
first: 'Student',
last: 'Four',
classes: [123]
},
{
id: 55,
first: 'Student',
last: 'Five',
classes: [123]
},
{
id: 66,
first: 'Student',
last: 'Six',
classes: [456]
},
{
id: 77,
first: 'Student',
last: 'Seven',
classes: [456, 789]
},
{
id: 88,
first: 'Student',
last: 'Eight',
classes: [456]
},
{
id: 99,
first: 'Student',
last: 'Nine',
classes: [456]
}
];
我的控制器看起来像这样:
var IndexController = Ember.ArrayController.extend({
actions: {
isActiveTog: function(id){
console.log(this);
console.log(this.store.get('model'));
var getter = this.get('classgroup');
console.log(getter);
}
},
classCount: function(){
return this.get('length');
}.property('@each')
});
export default IndexController;
这是我们的路由器:
import Students from "appkit/models/students";
import ClassGroup from "appkit/models/classgroup";
export default Ember.Route.extend({
model: function() {
return this.store.find('classgroup');
},
setupController: function(controller, model){
this._super(controller, model);
controller.set('students', this.store.find('students'));
controller.set('classgroup', this.store.find('classgroup'));
}
});
这是我们的车把模板中的each
块(我删除了其余部分,因为它太笨重了):
{{#each classgroup}}
<li id="c_{{unbound this.id}}" class="classMenu manageMenuWidth">
<span class="classSA" id="c_{{unbound this.id}}_sas"><input type="checkbox" name="c_{{unbound this.id}}_chk" id="c_{{unbound this.id}}_chk" /></span>
<span id="c_{{unbound this.id}}_nam" {{bind-attr class=":classLayout isActive:activeSelection"}} {{action "isActiveTog" this.id on="click"}}>{{unbound this.className}}</span>
{{#view 'toggleclass'}}<span class="togControl" id="c_{{unbound this.id}}_tog"></span>{{/view}}
</li>
<ul id="c_{{unbound this.id}}_sts" class="students manageMenuWidth">
{{#each students}}
<li class="student" id="s_{{unbound this.id}}_c_{{unbound classgroup.id}}">
<span class="studentChk" id="s_{{unbound students.id}}_c_{{unbound classgroup.id}}_img">{{unbound this.last}}, {{unbound this.first}}</span>
<input type="checkbox" name="s_{{unbound students.id}}_c_{{unbound classgroup.id}}_chk" id="s_{{unbound students.id}}_c_{{unbound classgroup.id}}_chk" />
</li>
{{/each}}
我尽可能多地包含了我们的代码,因为我对Ember仍然很新,我想确保你拥有所需的所有信息来帮助回答这个问题,即使这意味着给你得多。
因此,您没有太多挖掘,这里有更多信息。在把手模板中有一行 {{action&#34; isActiveTog&#34; this.id on =&#34;点击我们范围内的&#34;}} 。
这将调用我们的控制器isActiveTog
中的一个函数,我们希望用它来切换模型中isActive
的值,无论哪个&#34; classgroup&#34;在each
循环中单击了记录。
例如,用户点击&#34; Class 1&#34;,其中有isActiveTog
的动作调用,传入ID = 123.我希望我在控制器中的操作切换ClassGroup的值[123] [isActive]从0到1,反之亦然。
我可以说正确调用了我的控制器,因为我可以将{{classCount}}
放入我的模板中并查看&#34; 3&#34;在输出中。因此,问题是我无法找到一种方法来切换控制器中的值。
如何使用this.store.find()
搜索ID等于传递给操作的ID的classgroup
行,然后访问该类记录的isActive值。然后我需要使用this.store.set()
写回模型。
答案 0 :(得分:2)
看起来你是来自jQuery背景,因为你试图通过模板将你的ClassGroup记录的id
嵌入到DOM中(当然没有错,因为那就是我当我第一次开始使用来自jQuery背景的Ember时,我正在做的事情。如果你发现自己这样做,你可能会以非贪婪的方式做某事。通常,如果需要集成某些第三方jQuery库,则应该只按ID访问DOM元素。
好的,现在你知道应该注意我们应该如何以Ember的方式完成你想要的东西?
可能有几种方法可以实现,但对我来说效果很好的是为每个扩展ObjectController而不是ArrayController的ClassGroup创建另一个控制器。所以你会有
ClassGroupsController(ArrayController) - &gt; ClassGroupController(ObjectController)
请注意,阵列控制器是复数形式。这允许您做的是管理每个ClassGroup记录的状态,因为每个ClassGroup记录现在都有自己的控制器和自己的视图。
首先创建一个管理ClassGroups集合的数组控制器:
App.ClassGroupsController = Ember.ArrayController.extend({
});
然后,ClassGroupController(Object)应该有一个侦听click事件的视图。当我们得到一个click事件时,我们会在名为selected
的控制器(ClassGroupController)上触发一个动作。
App.ClassGroupView = Ember.View.extend({
templateName: 'classGroup',
/*
By specifying the tagName for this view we are telling ember
we want to wrap the view in a <tr> element. This is because
each classGroup is going to be a row in our table. By default
each view is wrapped in a <div>
*/
tagName: 'tr',
/*
This is the click handler that is called whenever the user
clicks on this view (in this case one of our <tr> elements
that is displaying our ClassGroup Model for us. The event
parameter is the jQuery event object.
*/
click: function(event){
/*
We want to forward this event to the controller where
we can do some logic based on the fact that it was clicked.
*/
this.get('controller').send('selected');
}
});
现在我们为ClassGroup创建ObjectController,它等待并监听当用户点击该selected
时ClassGroupView
发送的ClassGroup
操作。
App.ClassGroupController = Ember.ObjectController.extend({
actions:{
/*
This is the action we received from our view which was
based on the user clicking on one of the <li> elements
representing a ClassGroup Model
*/
selected: function(){
console.info("You selected: " + this.get('className'));
/*
Now we can easily toggle the isActive state of our model
*/
this.toggleProperty('isActive');
console.info("My isActive state is now: " + this.get('isActive'));
}
}
});
现在我们需要在模板中连接它。
{{#each itemController="classGroup"}}
{{view App.ClassGroupView}}
{{/each}}
注意我如何指定我想将classGroup用作我的ArrayController的itemController。在这里,我直接在模板中指定它。您也可以使用itemController
属性在ArrayController本身中指定它。例如:
App.ClassGroupsController = Ember.ArrayController.extend({
itemController: 'classGroup'
});
这是一个有效的JSFIddle,使用你的灯具来展示整个概念:
答案 1 :(得分:1)
直接回答你的问题
您可以按ID找到记录并使用
进行修改this.store.find('classgroup', id).then(function (classgroup) {
classgroup.toggleProperty('isActive');
});
但是在你的情况下,你真的不需要,因为你可以通过记录
所以在你看来使用
{{action "isActiveTog" this on="click"}}
代替this.id
,然后直接在控制器中修改它
isActiveTog: function(classgroup){
classgroup.toggleProperty('isActive');
// classgroup.save();
}