0

私はここ数週間、Ember の基礎を学ぼうとしていますが、現在、コントローラーのアクションを介してモデルのデータを変更する際に問題が発生しています。

私が見つけたすべての例は、1 次元フィクスチャを使用しているようです。私が使用しているフィクスチャは次のようになります。

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 に非常に慣れていないため、できるだけ多くのコードを含めました.

掘り下げすぎないように、ここにいくつかの追加情報を示します。handlebarsテンプレートには、スパン内に {{action "isActiveTog" this.id on="click"}}という行があります。

これは、ループ内でクリックされた「classgroup」レコードのモデル内のisActiveTogの値を切り替えるために使用するコントローラーの関数を呼び出します。isActiveeach

たとえば、ユーザーが「クラス 1」をクリックすると、 へのアクション コールがありisActiveTog、ID = 123 が渡されます。コントローラでのアクションで、ClassGroup[123][isActive] の値を 0 から 1 に切り替えるか、またはその逆にする必要があります。逆。

{{classCount}}テンプレートを挿入して出力に「3」が表示されるため、コントローラーが正しく呼び出されていると言えます。したがって、問題は、コントローラーで値を切り替える方法を理解できないことです。

アクションに渡されたものと同じ IDthis.store.find()を持つ行を検索し、そのクラス レコードの isActive 値にアクセスするにはどうすればよいでしょうか。classgroup次にthis.store.set()、モデルに書き戻すために使用する必要があります。

4

2 に答える 2

2

idテンプレートを介して ClassGroup レコードを DOM に埋め込もうとしている方法のため、jQuery のバックグラウンドから来ているようです(もちろん、Ember を最初に使い始めたときにそうしていたので、何も問題はありません)。 jQueryの重いバックグラウンドから来ています)。自分がこれを行っていることに気付いた場合は、おそらく、残り火以外の方法で何かを行っている可能性があります。通常、サードパーティの jQuery ライブラリを統合する必要がある場合は、ID でのみ DOM 要素にアクセスする必要があります。

さて、これで、Ember の方法であなたが望むことをどのように達成するべきか、何に注意すべきかがわかったでしょうか?

おそらくいくつかの方法がありますが、私にとってうまくいくのは、ArrayController の代わりに ObjectController を拡張する個々の ClassGroup ごとに別のコントローラーを作成することです。だからあなたは持っているでしょう

ClassGroupsController (ArrayController) -> ClassGroupController (ObjectController)

配列コントローラーが複数形になっていることに注意してください。これにより、個々の ClassGroup レコードの状態を管理できます。これは、各 ClassGroup レコードが独自のコントローラーと独自のビューを持つようになったためです。

まず、ClassGroup のコレクションを管理する配列コントローラーを作成します。

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');   
    }
});

ここで、ユーザーがその個人をクリックしselectedたときに から送信されるアクションを待機してリッスンする ClassGroup の ObjectController を作成します。ClassGroupViewClassGroup

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 として使用するように指定する方法に注意してください。ここでは、テンプレートで直接指定します。プロパティを使用して ArrayController 自体で指定することもできitemControllerます。たとえば、次のようになります。

App.ClassGroupsController = Ember.ArrayController.extend({
    itemController: 'classGroup'   
});

これは、フィクスチャを使用して概念全体を示す実際の JSFIddle です。

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

于 2014-03-28T23:33:41.037 に答える
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();
}
于 2014-03-29T07:13:44.810 に答える