Javascript 无法使用Ember API工具包更改模型数据

Javascript 无法使用Ember API工具包更改模型数据,javascript,ember.js,frameworks,ember-app-kit,Javascript,Ember.js,Frameworks,Ember App Kit,几周来,我一直在努力学习Ember的基本原理,当涉及到通过控制器中的操作更改模型中的数据时,我目前遇到了一个问题 我发现的所有示例似乎都使用一维夹具。我使用的固定装置如下所示: App.ClassGroup = DS.Model.extend({ className: DS.attr('string'), isActive: DS.attr('number'), students: DS.hasMany('Students',{async:true}), sele

几周来,我一直在努力学习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;
我的控制器如下所示:

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'));
    }
});
以下是我们的把手模板中的
每个
块(我删除了其余部分,因为它太大了):

{{#每个类组}
  • {{取消绑定this.className} {{{#视图'切换类'}{{/view}}
    • {{{每个学生}
    • {{解除绑定this.last},{{解除绑定this.first}
    • {{/每个}}
    我尽可能多地包含了我们的代码,因为我对Ember还是很陌生,我想确保您拥有帮助回答这个问题所需的所有信息,即使这意味着给了您太多

    为了避免你挖得太多,这里有更多的信息。在把手模板中,有一行{action“isActiveTog”this.id on=“click”}在我们的范围内

    这将在我们的控制器中调用一个函数,
    isActiveTog
    ,我们希望使用该函数在模型中为在
    每个
    循环中单击的任何“classgroup”记录切换
    isActive
    的值

    例如,用户单击“Class 1”,它有一个对
    isActiveTog
    的操作调用,传入ID=123。我希望我在控制器中的操作将ClassGroup[123][isActive]的值从0切换到1,反之亦然

    我可以说我的控制器被正确调用了,因为我能够将
    {{classCount}}
    放入我的模板中,并在输出中看到一个“3”。因此,问题是我无法找到在控制器中切换值的方法


    如何使用
    this.store.find()
    搜索ID等于传递给操作的任何内容的
    classgroup
    行,然后访问该类记录的isActive值。然后我需要使用
    this.store.set()
    写回模型。

    您似乎来自jQuery背景,因为您试图通过模板将类组记录的
    id
    嵌入DOM(当然,这没什么错,因为当我第一次开始使用来自jQuery的Ember时,我就是这么做的)。如果你注意到自己这样做了,你可能是在以非Ember的方式做一些事情。通常,如果你需要集成一些第三方jQuery库,你应该只通过ID访问DOM元素

    好了,现在你知道该注意什么了,我们应该如何以余烬的方式实现你想要的

    可能有几种方法可以实现这一点,但对我来说,有效的方法是为扩展ObjectController而不是ArrayController的每个类组创建另一个控制器

    ClassGroupsController(ArrayController)->ClassGroupController(ObjectController)

    请注意,数组控制器是多元的。这允许您管理每个类组记录的状态,因为每个类组记录现在都有自己的控制器和视图

    因此,首先创建一个数组控制器来管理类组集合:

    App.ClassGroupsController = Ember.ArrayController.extend({
    
    });
    
    然后,ClassGroupController(对象)应该有一个侦听单击事件的视图。当我们得到一个单击事件时,我们会在控制器(ClassGroupController)上触发一个名为
    selected
    的操作

    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');   
        }
    });
    
    现在我们需要在模板中连接这个

    {{#each itemController="classGroup"}}
        {{view App.ClassGroupView}}  
    {{/each}}
    
    请注意,我是如何指定要将类组用作ArrayController的itemController的。在这里,我直接在模板中指定它。您也可以使用
    itemController
    属性在ArrayController本身中指定它。例如:

    App.ClassGroupsController = Ember.ArrayController.extend({
        itemController: 'classGroup'   
    });
    
    下面是一个正在工作的JSFIDLE,使用您的装置演示整个概念:


    您似乎来自jQuery背景,因为您试图通过模板将类组记录的
    id
    嵌入到DOM中(当然这没什么错,因为这是我第一次从jQuery背景开始使用Ember时所做的)。如果您注意到自己在这样做,则可能是在以非余烬的方式进行操作。通常,如果需要集成某些第三方jQuery库,则只应通过ID访问DOM元素

    好了,现在你知道该注意什么了,我们应该如何以余烬的方式实现你想要的

    可能有几种方法可以实现这一点,但对我来说,有效的方法是为扩展ObjectController而不是ArrayController的每个类组创建另一个控制器

    ClassGroupsController(ArrayController)->ClassGroupController(ObjectController)

    请注意,数组控制器是多元的。这允许您管理每个类组记录的状态,因为每个类组记录现在都有自己的控制器和视图

    因此,首先创建一个数组控制器来管理类组集合:

    App.ClassGroupsController = Ember.ArrayController.extend({
    
    });
    
    然后,ClassGroupController(对象)应该有一个侦听单击事件的视图。当我们得到一个单击事件时,我们会在控制器(ClassGroupController)上触发一个名为
    selected
    的操作

    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');   
        }
    });
    
    现在我们需要在模板中连接这个

    {{#each itemController="classGroup"}}
        {{view App.ClassGroupView}}  
    {{/each}}
    
    注意如何