【问题标题】:How do views or parts of the appication communicate with each other in emberjsember js中视图或应用程序的部分如何相互通信
【发布时间】:2014-02-11 15:50:21
【问题描述】:

我最近正在研究 emberjs。我有一个关于视图如何相互交流的问题。我知道视图不通信,所以问题可能是 Route 或 Controller(视图模型)。

来自其他框架和语言,我使用了一种称为 pubsub 的模式来传播某些信息已更改的信息,并且其他视图(对此信息感兴趣的人)将订阅并在发送事件/消息时更新.

这也是适用于 emberjs 哲学的模式吗?或者您将如何根据其他部分的更改更新 UI 上的不同部分?

一个(非常)简单的例子可能是:

-> Application
  -> Navigation which contains a Link to the posts route with a number of current posts (count)
  -> Posts route would have a list of post with details (and add,delete,etc) actions

现在,当我创建帖子时,它将被添加到列表中,我应该如何更新导航中的帖子数?

显然,这可能/应该也适用于更复杂的示例。 作为说明: 目前,我还有一个用于统计数据的服务器路由。所以导航和它的帖子数将从服务器获取,它不绑定到帖子数组的长度...

使用 emberjs 处理此类问题的最佳方法是什么?

【问题讨论】:

    标签: javascript ember.js publish-subscribe


    【解决方案1】:

    正如http://emberjs.com/guides/views/ 中所述,视图主要用于处理用户事件和创建可重用组件。然而,一些有用的事实是,

    1View 的模板将呈现的内容基于对应的Controller 所拥有的模型和属性。

    2.A View 可以访问它对应的Controller 以及任何其他关联的控制器(通过needs 属性http://emberjs.com/guides/controllers/dependencies-between-controllers/)和它们持有的数据。

    3。如果视图共享一个模型,那么它们将在模型更改时更新。发生这种情况有几种情况,最常见的一种是通过 {{view}} 助手插入视图。(http://emberjs.com/guides/views/inserting-views-in-templates/)

    4。如果视图或其对应的控制器正在观察或绑定到公共属性,那么它们也将被更新 (http://emberjs.com/guides/object-model/classes-and-instances/)。

    考虑到这些事实,可以根据特定系统的要求来解决这个特定问题。例如一些选项可能是(附有粗略的例子),

    http://emberjs.jsbin.com/huqoq/1/edit

    • 如果数据是延迟加载的,例如在页面中,然后让Navigation 控制器observe 更改Posts 控制器上的帖子枚举,可能会触发对服务器的请求以检索帖子总数或根据操作更新计数器值(创建/删除)。

    http://emberjs.jsbin.com/jomes/1/edit

    • Navigation 视图可以简单地插入到 Posts 视图中并共享相同的模型,并具有显示帖子总数的计算属性。

    http://emberjs.jsbin.com/xujap/1/edit

    http://emberjs.jsbin.com/gihep/1/edit

    【讨论】:

      【解决方案2】:

      这在 Ember.js 中非常简单。有不同的设置方法,但基本如下: 由于 Ember 是一个 MVC 框架,因此您的所有视图都可以访问相同的底层数据。当您对数据进行更改时,Ember 的数据绑定将确保所有关心该更改的视图都将得到更新。

      因此,特别是对于您提到的示例,您可以简单地在模板中包含 {{ content.length }},它将显示 ArrayController 中的项目数(由 Ember 自动生成,但如果您想添加,可以覆盖它功能)。看看this jsFiddle

      模板:

      <script type="text/x-handlebars" data-template-name="application">
          <h1>ember-latest jsfiddle</h1>    
          {{ render 'navigation' controllers.users.content }}
          {{outlet}}
      </script>
      
      <script type="text/x-handlebars" data-template-name="navigation">
            <h2>Index Content ({{ content.length }}):</h2>
      </script>
      
      <script type="text/x-handlebars" data-template-name="index">
        <ul>
        {{#each}}
            <li>{{firstName}} {{lastName}}</li>
        {{/each}}
         </ul>
         <button {{action 'add'}}>Add</button>    
      </script>
      

      路线:

      App.ApplicationRoute = Ember.Route.extend({
          setupController: function() {
              this.controllerFor('users').set('content', this.store.findAll('user'));
          }
      });
      
      App.IndexRoute = Ember.Route.extend({
          model: function() {
              return this.store.findAll('user');
          }
      });
      

      控制器:

      App.ApplicationController = Ember.Controller.extend({
          needs: ['users'],
      });
      
      App.IndexController = Ember.ArrayController.extend({
          actions: {
              add: function() {
                  this.get('store').createRecord('user', {firstName: 'New', lastName: 'Person'});
              }
          }
      });
      

      当您点击按钮时,您会看到计数如何自动更新。请注意,在这种情况下,我们只有一个路由(以更好地说明数据绑定),但如果您有一个索引路由(列出所有帖子)和一个详细路由(显示单个帖子),这将同样有效。

      欢迎来到 Ember.js 的神奇世界 :)

      【讨论】:

      • 感谢您的回复和代码示例。问题是 count 将超出 IndexController 范围。导航位于 {{outlet}} 上方的应用程序模板中。并且应该从服务器中提取计数,而不是通过 ajax 绑定到长度
      • 我更新了我的答案以解决您的评论。所有这些都是可能的——我使用 DS.FixturesAdapter 来模拟服务器。通常你会使用 DS.RESTAdapter 之类的东西,它会处理你与后端的通信。因此,例如,当您调用this.store.findAll('user') 时,它会向/users 发送GET 请求,并且您的数据(以及您的“计数”)会自动更新。在我的编辑中,我还删除了计算属性 count,因为 Handlebars 允许您通过 {{ content.length }} 获取内容的长度
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 2012-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多