2

我有一个ProfilesController和一个ProfileController代表一个单一的个人资料。

// Profiles listing
App.ProfilesController = Ember.ArrayController.extend({

});

// Single Profile representation
App.ProfileController = Ember.ObjectController.extend({

    isActive: false,

    actions: {

        edit: function() {

            // TODO: disable all profiles
            // does not work ... parentController is undefined. pseudo code only!
            this.get('parentController.children').forEach(function(profile) {
                profile.set('isActive', false);
            });

            // enable current profile
            this.set('isActive', true);
        }
    }
});

请注意,这不是完整的代码,这 2 个控制器在我的应用程序中有更多代码,并且还有一个 ProfileView 可以使配置文件列表成为可能。

重要的部分是如何从 ProfileController 中访问父 ProfilesController(ArrayController)?

我已经尝试过(在编辑操作中):

this.get('parent') // => undefined
this.get('parentController') // => null
this.get('target') // => null

编辑:与此同时,我沿着对象树走下去,我想出了一个令人难以置信的 hacky 但可行的解决方案:

// disable all profiles
this.get('controllers.profiles.target._activeViews.profiles.0._childViews.0._childViews').forEach(function(childView) {
    childView.get('_childViews.0.controller').set('isActive', false);
});

它一直有效,直到我改变我的模板结构中的某些内容。必须有一种更清洁的方法来做到这一点:-D

编辑2:为了澄清一点,这是我的配置文件模板,其中profiles是配置文件模型的集合(不是控制器!每个模型都由控制器表示,因为我必须存储应用程序状态,如当前活动配置文件等):

{{#each profile in profiles}}
    {{view App.ProfileView profileBinding=profile}}
{{/each}}

和 ProfileView

App.ProfileView = Ember.View.extend({

     templateName: 'profiles/profile',

     init: function() {
         this._super();
         var profile = this.get('profile');

         // Here I explicitely create a ProfileController instance, 
         // otherwise ProfilesController would be used instead of ProfileController 
         // because in EmberJS by default the View's controller is always the parent controller
         this.set('controller', App.ProfileController.create());
         var controller = this.get('controller');
         controller.set('profile', profile);            
     }
});
4

2 回答 2

4

您可以itemController在循环中设置属性,each这样您就不必手动创建ProfileControllers.

{{#each profile in profiles itemController="profile"}}
    {{view App.ProfileView profileBinding=profile}}
{{/each}}

然后您可以使用needs来确保对 的引用ProfilesController被注入到每个ProfileController. 您将this.get('controllers.profiles')用于访问ArrayController自身。如果您正在使用 Ember 方式做事,您会想要访问该content控制器的属性 ( this.get('controllers.profiles.content'))。看起来您没有按照 Ember 方式进行操作,而是将集合添加到该profiles控制器的属性而不是content属性。在这种情况下,你会使用this.get('controllers.profiles.profiles'). 的第一个实例profiles获取ProfilesController,第二个实例获取profiles在该控制器上设置的属性。

App.ProfileController = Ember.ObjectController.extend({
    needs: ['profiles'],
    actions: {
        edit: function() {

            this.get('controllers.profiles.profiles').forEach(function(profile) {
                profile.set('isActive', false);
            });

            // enable current profile
            this.set('isActive', true);
        }
    }
});
于 2013-10-08T21:14:47.623 回答
1

你想让它隐式(就像在任何其他语言中使用 super 一样)还是将你想要访问的控制器命名为显式就足够了?

请参阅此链接:http ://eviltrout.com/2013/02/04/ember-pre-1-upgrade-notes.html

在您的情况下,它将是:

App.ProfileController = Ember.ObjectController.extend({
    needs: ['profiles'],
    actions: {
        edit: function() {

            this.get('controllers.profiles').forEach(function(profile) {
                profile.set('isActive', false);
            });

            // enable current profile
            this.set('isActive', true);
        }
    }
});
于 2013-10-08T16:47:09.487 回答