ember.js,ember-cli:奥特莱斯没有正确嵌套

han*_*ole 1 ember.js ember-cli

我遇到了一个问题,我无法在我的Ember CLI应用程序中正确显示嵌套插件.我想要的视图树如下:

  • application(所有资源的列表,其中client_availability为1)
  • - client_availabilities.index(client_availabilities列表)
  • - client_availability(个人client_availability)

这与Ember Starter Kit中的"application> posts.index> post"层次结构非常相似.我想要的行为是当我导航到client_availabilities.index时出现在"mainoutlet"中的client_availability列表,然后当我在"suboutlet"中调出一个单独的client_availability时,它会持续存在.

容易,对吗?这是默认行为以及为什么我们都喜欢Ember.但是,我似乎无法让它发挥作用.当我在client_availabilities.index中明确地指定我的命名子输出并单击单个client_availability时,任何插座中都没有显示任何内容:

场景1:在client_availabilities中渲染子输出

/app/template/application.hbs:

    {{link-to 'Client Availabilities' 'client_availabilities'}}

    {{outlet 'mainoutlet'}}
Run Code Online (Sandbox Code Playgroud)

/app/template/client-availabilities/index.hbs:

    {{outlet 'suboutlet'}}
Run Code Online (Sandbox Code Playgroud)

/app/routes/client-availabilities/index.js:

    import Ember from 'ember';

    export default Ember.Route.extend({

      renderTemplate: function(){
          this.render({
            into: "application",
            outlet: "mainoutlet"
          });
      },

      model: function() {
        return this.store.find('client_availability');
      }

    });
Run Code Online (Sandbox Code Playgroud)

/app/routes/client-availability.js:

    import Ember from 'ember';

    export default Ember.Route.extend({

      renderTemplate: function(){
          this.render('client_availability', {
            into: "client_availabilities",
            outlet: "suboutlet"
          });
      },

      model: function(params) {
        return this.store.find('client_availability', params.client_availability_id);
      }

    });
Run Code Online (Sandbox Code Playgroud)

或者,当我在应用程序中定位我的mainoutlet时,client_availability出现在"suboutlet"client_availabilities.index从"mainoutlet"中消失:

场景2:在应用程序内渲染子输出

/app/template/application.hbs:

    {{link-to 'Client Availabilities' 'client_availabilities'}}

    {{outlet 'mainoutlet'}}

    {{outlet 'suboutlet'}}
Run Code Online (Sandbox Code Playgroud)

/app/template/client-availabilities/index.hbs :(空)

/app/routes/client-availabilities/index.js:

    import Ember from 'ember';

    export default Ember.Route.extend({

      renderTemplate: function(){
          this.render({
            into: "application",
            outlet: "mainoutlet"
          });
      },

      model: function() {
        return this.store.find('client_availability');
      }

    });
Run Code Online (Sandbox Code Playgroud)

/app/routes/client-availability.js:

    import Ember from 'ember';

    export default Ember.Route.extend({

      renderTemplate: function(){
          this.render('client_availability', {
            into: "application",
            outlet: "suboutlet"
          });
      },

      model: function(params) {
        return this.store.find('client_availability', params.client_availability_id);
      }

    });
Run Code Online (Sandbox Code Playgroud)

这是我的路由器,两种情况都一样:

/app/router.js:

    import Ember from 'ember';

    var Router = Ember.Router.extend({
      location: 'auto'
    });

    Router.map(function() {
      this.resource('client_availabilities', function() {
        this.resource('client_availability', { path: ':client_availability_id' });
      });
    });

    export default Router;
Run Code Online (Sandbox Code Playgroud)

我很乐意分享更多代码,但应用程序被分成几个文件,遗憾的是我不能完整发布.谁能看到我做错了什么?该应用程序的其余部分工作正常,我似乎无法让这个基本行为工作.

Bot*_*oke 8

你有一个只有{{outlet}}的/app/templates/client-availibilities.hbs模板吗?如果没有这个,应用程序将失去它在插座树中的位置.Ember-CLI和Ember Starter Kit在结构上彼此非常不同,所以我可以看到混乱的来源.

我如何看待Ember的渲染风格是模板文件夹中的每个把手文件(即/templates/users.hbs)表示应用程序从一个主题到另一个主题的整体状态的变化(例如:从新闻源到用户).templates文件夹中的相应子文件夹会更改主题本身的状态.

例如:

  • 必需的模板
    • 用户容器或应用程序范围内唯一的用户页面位于/templates/users.hbs
  • 可选模板
    • 用户索引位于/templates/users/index.hbs
    • 用户展示将在/templates/users/show.hbs
    • 用户New将位于/templates/users/new.hbs

没有[/templates/users/*.hbs]你可以[/templates/users.hbs]并且仍然可以跟踪你的数据; 但是,如果没有[/templates/users.hbs],您不能拥有[templates/users/index.hbs],并且仍然可以跟踪您的数据.为什么?想象一下,如果你导航到somesite.com/users.目前没有顶级模板,其中Ember可以呈现[users/index.hbs]模板.[/templates/users.hbs]模板填补了这一空白,同时也充当了/ templates/users文件夹中所有其他页面的容器.

例如,在您的应用程序方面,为了在用户访问http://www.yourwebsite.com/client-availibilities时呈现[/app/templates/client-availibilities/index.hbs] ,您的应用程序将需要定义了这些模板,以便ember可以深入到它们中.

application.hbs                     // and in its outlet, it will render...
--client-availibilities.hbs         // and in its outlet, it will render by default...
----client-availibilities/index.hbs // then, for the client-availability (singular), you can have ember render it in
----client-availibilities/show.hbs  // will render also in the client-availabilites as it is a separate state of the subject. Can also be nested inside the index route within the router so that it renders inside the index template.
Run Code Online (Sandbox Code Playgroud)

事实上,我会构建你的应用程序......

/app/router.js

... // previous code

  Router.map(function() {
    this.resource('client_availabilities', function() {
      this.route('show', { path: '/:client_availability_id' });
      // this.route('new');  ! if needed !
      // this.route('edit', { path: '/:client_availability_id/edit' ); ! if needed !
    });
  });

... // code
Run Code Online (Sandbox Code Playgroud)

/app/templates/application.hbs

{{link-to 'Client Availabilities' 'client_availabilities'}}

{{outlet}}
Run Code Online (Sandbox Code Playgroud)

/app/templates/client-availabilities.hbs

{{outlet}}
Run Code Online (Sandbox Code Playgroud)

/app/templates/client-availabilities/index.hbs

<ul>
  {{#each}}
    {{#if available}}       
      <li>
        {{#link-to #link-to 'client-availabilities.show' this}}
          {{firstName}} {{lastName}}
        {{/link-to}}
      </li>
    {{/if}}
  {{else}}  <!-- we want this to only render if the each loop returns nothing, which is why it's outside the if statement -->
    <li>Nobody is available</li>
  {{/each}}
</ul>

<!-- Note: you don't need to put an outlet here because you're at the end of the tree -->
Run Code Online (Sandbox Code Playgroud)

/app/templates/client-availabilities/show.hbs

<!-- Everything you want to show about each availability -->>
<!-- Note: you don't need to put an outlet here because you're at the end of the tree -->
Run Code Online (Sandbox Code Playgroud)

/app/routes/client-availabilities/index.js

import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    return this.store.findAll('client_availability');
  }
});
Run Code Online (Sandbox Code Playgroud)

/app/routes/client-availabilities/show.js

import Ember from 'ember';

export default Ember.Route.extend({
  model: function(params) {
    return this.store.find('client-availability', params.client_availability_id);
  }
});
Run Code Online (Sandbox Code Playgroud)

/app/models/client-availability.js

import DS from 'ember-data';

var client-availability = DS.Model.extend({
  firstName: DS.attr('string'),
  lastname:  DS.attr('string'), 
  available: DS.attr('boolean'),
  available_on: DS.attr('date')
});

export default client-availability;
Run Code Online (Sandbox Code Playgroud)

但是,您确定要根据每个客户的可用性来构建应用程序吗?每个客户端构建它然后过滤每个客户端以显示它们是否可用是不是更有意义?资源应该是名词,路径应该是形容词.因此,最好使用客户端作为模型而不是其可用性,并在模型上具有isAvailable属性(如上例所示)或与其他可用性模型的一对多关联(如果您想要显示具有多种可用性的客户(如下所示).

例如,

/app/models/client.js

import DS from 'ember-data';

var Client = DS.Model.extend({
  firstName: DS.attr('string'),
  lastName:  DS.attr('string'), 
  availabilities: DS.hasMany('availability')
});

export default Client;
Run Code Online (Sandbox Code Playgroud)

/app/models/availability.js

 import DS from 'ember-data';

 var Availability = DS.Model.extend({
   date:   DS.attr('date'),
   client: DS.belongsTo('client')
 });

 export default Availability;
Run Code Online (Sandbox Code Playgroud)

从长远来看,后一种方法会将您的应用设置为立即显示所有可用性,并允许用户通过客户端进行过滤,此外,它还允许用户查看客户端并查看其所有可用性.使用原始方法(客户端模型上的isAvailable属性),用户只能从客户端模型本身获取可用性,但如果用户想要查看3月3日中午可用的所有客户端,该怎么办?好吧,如果没有与客户端模型相关联的可用性模型,您将不得不将大量代码放入客户端控制器中,如果沿着一对多路径,ember会默认为您提供这些代码.

如果您需要更多建议,请告知我们.我非常乐意添加您需要的模板,控制器和路由的更多示例,以便实现此目的.