在Ember中使用条件

时间:2013-04-09 16:54:08

标签: ember.js handlebars.js ember-router

这是我的jsfiddle链接,我试图在DropDown下面打印一条消息 - 选择B以外的任何选项时选择选项B.

选择选项B时,我必须打印Id和选项名称

http://jsfiddle.net/fortm/MGX9k/1/

发生的事情是“选择选项B”消息永远不会被打印出来。始终显示ID和名称。

因此,Handlebar条件存在一些问题 -

{{#if App.SearchController.selectedB}}

其中,selectedB是一个函数,当Option为B时返回true,但这似乎不起作用..

  selectedB: function() {
    return this.get('selectedName.id') == 2 ;
  }

作为一个附带问题,我需要设置Select Dropdown样式,所以我添加了“class”atrribute。它有自定义样式但它仍然有ember-select作为样式之一..我们可以在添加新的自己样式时删除ember CSS吗?

2 个答案:

答案 0 :(得分:2)

我在这里看到的问题并不是关于条件本身,而是关于你如何使用你的数据。一些事情:

(你可以在这里看到更多:http://jsfiddle.net/schawaska/enRhT/

如果您希望模板在selectedB上做出反应,则必须将其设置为computed property,同时指定其依赖项,在您的情况下为selectedName属性:

selectedB: function() {
    return this.get('selectedName.id') == 2;
}.property('selectedName') // This is important

另外,我注意到你在模板中将绑定分配给控制器类而不是实例。考虑更改您的应用程序以包含Router,这将允许您以不同方式设置模型数据。

使用路由机制,控制器将被分配到您的路由并自动绑定到视图/模板,因此您可以使用App.SearchController.property或{{1}来绑定到controller,而不是绑定到controller.property。 }}:

{{view Ember.Select class="my_custom_class"
    contentBinding="controller.content"
    optionValuePath="content.id"
    optionLabelPath="content.firstName"
    selectionBinding="controller.selectedName"}}

这需要进行一些更改。

设置路由器

App.Router.map(function() {
    this.route('search');
});
// this would require that you either create an IndexRoute 
// to redirect from the root to the SearchRoute, or
// change the route path: this.route('search', { path: '/' }); 

从路线的模型功能返回数据,而不是从控制器返回

App.SearchRoute = Em.Route.extend({
    model: function() {
        return [
            {firstName: "Any",  id: 0},
            {firstName: "A",    id: 1},
            {firstName: "B",    id: 2},
            {firstName: "C",    id: 3},
            {firstName: "D",    id: 4},
            {firstName: "E",    id: 5}
        ];
    }
});

{{outlet}}添加到应用程序模板

<script type="text/x-handlebars">
{{outlet}}
</script>

使用正确的controller

将模板正文移动到特定模板

现在,因为路由提供了控制器及其数据,所以您应该能够在Handlebars模板中使用controller键,它将引用SearchController(见下文)。

<script type="text/x-handlebars" data-template-name="search">
    {{view Ember.Select class="my_custom_class"
       contentBinding="controller.content"
       optionValuePath="content.id"
       optionLabelPath="content.firstName"
       selectionBinding="controller.selectedName"}}

    {{#if selectedB}}
      <p>Selected: {{controller.selectedName.firstName}}
      (ID: {{controller.selectedName.id}})</p>
    {{else}}
    <p>Select option B</p>
    {{/if}}    
</script>

修复控制器

App.SearchController = Ember.ArrayController.extend({
  selectedName: null,
  selectedB: function() {
    return this.get('selectedName.id') == 2 ;
  }.property('selectedName')
});

由于naming conventions,您的路线希望您的应用拥有SearchController(此确切名称),这就是它将所有内容连接在一起的方式。如果您的控制器没有实现ArrayController,它会爆炸,因为您的模型函数现在返回ModelArray并且它不会绑定到ObjectController(默认值)

答案 1 :(得分:1)

这是一个working version。以下是我改变的一些最重要的事情:

  1. 我已将您的内容设置移到SearchRoute所属的位置:

    App.SearchRoute = Ember.Route.extend({
      model: function () {
        return [
          Ember.Object.create({firstName: "Any", id: 0}),
    
  2. 我修改了您的搜索控制器以使用extend代替create,并使selectedB成为计算属性:

    App.SearchController = Ember.ArrayController.extend({
      selectedName: null,
    
      selectedB: function() {
        // Be careful! If you use Ember Data, the key will be '2', not 2.
        return this.get('selectedName.id') === 2;
      }.property("selectedName.id")
    });
    
  3. 我给了SearchController自己的模板,并修改了代码以使用相对属性,而不是尝试作为全局访问控制器。我还联系了contentBinding指向您的搜索控制器,该控制器充当您实际内容的代理。

    <script type="text/x-handlebars" data-template-name="search">
    
      {{view Ember.Select class="my_custom_class"
             contentBinding="this"
             optionValuePath="content.id"
             optionLabelPath="content.firstName"
             selectionBinding="selectedName"}}
    
  4. 还有其他一些小的变化。