【问题标题】:Unable to Alter Model Data Using Ember API Kit无法使用 Ember API 工具包更改模型数据
【发布时间】:2014-05-08 13:31:20
【问题描述】:

几周以来,我一直在尝试学习 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 "isActiveTog" this.id on="click"}} 在我们的范围内。

这将调用我们控制器中的一个函数isActiveTog,我们希望使用该函数来切换模型中isActive 的值,以便在each 循环中单击任何“类组”记录。

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

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

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

【问题讨论】:

    标签: javascript ember.js frameworks ember-app-kit


    【解决方案1】:

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

    好的,现在你知道要注意什么了吗?我们应该如何以 Ember 方式完成你想要的?

    可能有几种方法可以解决它,但对我来说最有效的是为每个单独的 ClassGroup 创建另一个控制器,该控制器扩展 ObjectController 而不是 ArrayController。所以你会有

    ClassGroupsController (ArrayController) -> ClassGroupController (ObjectController)

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

    所以首先创建一个数组控制器来管理ClassGroups的集合:

    App.ClassGroupsController = Ember.ArrayController.extend({
    
    });
    

    ClassGroupController (Object) 应该有一个监听点击事件的视图。当我们收到点击事件时,我们会在控制器 (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');   
        }
    });
    

    现在我们为 ClassGroup 创建 ObjectController,它正在等待并侦听当用户单击该个人 ClassGroup 时从 ClassGroupView 发送的 selected 操作。

    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,使用您的固定装置来演示整个概念:

    http://jsfiddle.net/NQKvy/872/

    【讨论】:

    • 太棒了!这对办公室的我们来说是一个巨大的帮助,所以我们都继续前进并投票赞成这个答案。你说得对,我们以 jQuery 的思维方式进入这个问题,我想我们需要打破这些习惯才能使用 Ember。一旦我们改变了事情并决定使用带有itemController 指向对象控制器的数组控制器,一切就都到位了。这是一个“啊哈!”片刻。感谢您将 jsFiddle 示例记录得这么好。
    【解决方案2】:

    直接回答你的问题

    您可以通过 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();
    }
    

    【讨论】:

      猜你喜欢
      • 2015-11-13
      • 2017-05-21
      • 2012-06-11
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多