【问题标题】:Controller and model data store access ember.js控制器和模型数据存储访问 ember.js
【发布时间】:2013-09-05 00:55:01
【问题描述】:

我目前正在使用“ember-1.0.0-rc.7.js”来管理我的 ember 应用程序的持久性和数据存储。

user.js

App.User = DS.Model.extend({
    firstName:     DS.attr('string'),
    lastName:      DS.attr('string'),
    category:      DS.attr('string'),
    status:        DS.attr('string'),
    position:      DS.attr('string'),
    fullName:      function()
    {
       return '%@ %@'.fmt(this.get('firstName'), this.get('lastName'))
    }.property('firstName', 'lastName')
});

App.User.FIXTURES = 
[
 {
   id:          1,
   firstName:   'Derek',
   lastName:    "H",
   category:    "admin",
   status:      "offline",
   position:    "3232"
 },
 {
   id:          2,
   firstName:   'Jim',
   lastName:    "H",
   category:    "admin",
   status:      "online",
   position:    "322"
 }
];

UserListController.js

App.UserListController = Ember.ArrayController.create({
    content: [],
    users: App.User.find()
});

store.js

App.Store = DS.Store.extend({
  revision: 12,
  adapter: 'DS.FixtureAdapter'
});

从上面,我假设 App.User.find() 会返回给我所有的用户。但是,我收到以下错误:

来自 Firebug 的错误:

Your application does not have a 'Store' property defined. Attempts to call 'find' on model classes will fail. Please provide one as with 'YourAppName.Store = DS.Store.extend()'
TypeError: store is undefined

消息没有意义,但商店是为 App 定义的。如果商店没有定义,那么下面的代码将不起作用。

在下面的代码中,我在路由的上下文中调用 App.User.find() 并且它可以工作。

路由器.js

Bib.Router.map(function () {
  this.resource('index', { path: '/' });
});


App.IndexRoute = Ember.Route.extend({
  model: function () {
    return ['a','b', 'c' ];
  },
  renderTemplate: function () {
        this.render();
        this.render('userList', { outlet: 'userList', into: 'application', controller: App.UserListController });//render the list in list outlet
  },
  setupController: function (controller, model) 
  {
     controller.set('menu', model);
     controller.set('test', App.User.find());
  }
});

在 index.html 中

<script type="text/x-handlebars" id="userList" data-template-name="userList">
   {{#each controller}}
       {{firstName}}
   {{/each}}
</script>

我希望那里的控制器代表 UserListController 并让它具有对用户模型的引用。请记住,我无法将其连接到路由中,因为我只有一个用于此应用程序的路由。

我相信这是由于我拨打电话的背景造成的。换句话说,在 Controller 中使用它。我可能不理解控制器和模型之间如何相关的基本概念。

任何建议表示赞赏, 谢谢, D

【问题讨论】:

  • 确保您在致电.find()之前定义您的商店

标签: model ember.js controller


【解决方案1】:

可以在控制器中进行find 调用。但是,UserListController.js 中的情况并非如此。

您呼叫的是Ember.ArrayController.create,而不是Ember.ArrayController.extend。也就是说,您正在创建一个ArrayController 的全局实例,而不是定义一个新的控制器类。

在进行此find 调用时,在评估UserListController.js 时,尚未设置您定义的商店。

您可以通过删除此代码并在您的应用启动后在浏览器控制台中对其进行评估来看到这一点。

但是,不鼓励创建全局控制器并在其上手动设置数据。 Ember 应用程序中的常见模式是创建控制器类,这些控制器类被实例化,然后通过路由填充数据。

例如:

App.Router.map(function () {
  this.resource('user', { path: '/' });
});

App.UserIndexRoute = Ember.Route.extend({
  model: function () {
    return App.User.find();
  }
});

这将自动创建一个UserIndexController,它是一个Ember.ArrayController,并将其content 设置为App.User.find()

现在,这是一个简化的示例,而不是您想要做的。看起来您想将存储在 UserListController 中的用户列表呈现到主模板上的插座中。

为此,您需要以下内容:

App.Router.map(function() {
  // you don't need to create an index resource
  // an IndexRoute is created by default
});

App.UserListController = Ember.ArrayController.extend();

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return ['a', 'b', 'c'];
  },

  setupController: function (controller, model) {
    controller.set('menu', model);
    this.controllerFor('userList').set('content', App.User.find());
  },

  renderTemplate: function() {
    var controller = this.controllerFor('userList');
    this.render();
    this.render('userList', {controller: controller});
  }
});

【讨论】:

  • 是的,这仍然不起作用。你对我要做什么有了大致的了解。我基本上想将有权访问 User.find() 模型的 userListController 传递到呈现模板的函数中。所以在模板中我可以 {{#each controller}} {{firstName}} {{/each}} 例如。我测试了上面的代码,它无法识别控制器。我的意思是我总是可以通过我在 setupController 中定义的 userList 进行循环,但这似乎不是正确的方向。
  • 我已经阐明了我正在寻找的示例。它从不循环打印数据。
  • 哦,很好,贾斯汀,我完全错过了那里发生的创建与扩展的事情。
【解决方案2】:

问题可能是由users: App.User.find() 行引起的。对find() 的调用可能是在首次评估模型时调用的,这可能是在定义您的商店之前。 Ember Way (tm) 是使用路由为您的控制器设置模型。无论您的路由中的 model 方法返回什么,都将设置为控制器中的 'content' 属性。

App.UserListRoute = Ember.Route.extend({
  model: function() {
    return App.User.find();
  }
});

App.UserListController = Ember.ArrayController.create({
  // you don't need anything here 
  // the model from the route will be set to 'content'
});

如果您需要'content' 属性为空白,并且您需要列表位于'users' 属性中,您可以这样做。

App.UserListRoute = Ember.Route.extend({
  setupController: function() {
    this.controller.set('content',[]);
    this.controller.set('users', App.User.find());
  }
});

App.UserListController = Ember.ArrayController.create({
  // still don't need anything here
});

【讨论】:

  • 是的,这就是导致问题的行。问题是我只有一条路线(主要路线)。我想用不同的控制器对模板进行不同的渲染,并将特定的功能隔离到控制器本身,而不是把范围交给主控制器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-06
  • 2016-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多