如果对象数组的权限为true,则选中复选框

时间:2013-08-07 14:08:53

标签: templates backbone.js handlebars.js

我正在使用骨干和把手一个月,我遇到了这个问题。

我从模型中得到了这个对象:

Object {list: Object, permissions: Object}
  list: Object
        0: Object
           id: "1"
           name: "cms"
           __proto__: Object
        1: Object
        2: Object
        3: Object
  permissions: Object
         analytics: true
         categories: false
         cms: true
         coupons: false

现在有了把手,我试图找出当相对权限值为真时如何检查框:

{{#each list}}
 <tr>
  <th><input type="checkbox" id="{{id}}" 
        {{#each permission}}    
            {{#ifCond this {{name}} }}//that's where my current error is when I try to precompile this template,the syntax is wrong
                checked
            {{/ifCond}}
        {{/each}}
      />{{name}}
  </th>
 </tr>
{{/each}}

ifCond是我在handlebars.js中构建的一个函数:

Handlebars.registerHelper('ifCond', function(v1, v2, options) {
  if(v1 === v2) {
    return options.fn(this);
  }
  return options.inverse(this);
});

希望有人可以帮助我!!

谢谢!

1 个答案:

答案 0 :(得分:2)

如果首先没有帮助程序,那就是编写模板的方法。 从这一点开始

Without Helper

在模板中,您试图迭代对象,这不是正确的方法。 您应该将其留给模板助手来处理传递正确上下文的内容。

                       ---- This is again wrong ( something in these lines)
                      |                compare="name"
    {{#ifCond this {{name}} }}  
                ^
        ^       -----  Context
        |
   Name of helper
   under which it is 
   registered

当您将值传递给compare=name时,该值将替换为该对象的键值。

但请记住,您已经在每个循环内部迭代list对象。

所以this将指向该对象。因此,您需要使用 ../ 返回父对象1步,这样您就可以访问权限对象。

{{#ifCond this compare=name }}

将映射到帮助程序的参数。

'ifCond', function(v1, v2, options) {

v1 将为this context v2 将映射到handlebar options 选项将在帮助程序中传递undefined as no 3rd argument

因此模板将是这种形式

 {{#ifCond this obj=../this compare=this.name}} 
  • - 每个(环路中的当前对象)的上下文
  • obj = 将被转储到options.hash对象中。这是主要目标。
  • 比较将是此上下文中的name属性

映射到

  'ifCond', function (context, options) 

所以你的模板结构如下所示

<强>模板

 <script type="text/template" id="handlebar-template">
       {{#each list}}
           <tr>
             <th>
                 <span>
                     <input type="checkbox" id="{{id}}" 
                     {{#ifCond this obj=../this compare=this.name}} 
                          checked 
                     {{/ifCond}} />
                 </span>
                 <span class="name">{{name}}</span>
             </th>
          </tr>
       {{/each}}
    </script>

<强>辅助

Handlebars.registerHelper('ifCond', function (context, options) {
    var permissions = options.hash.obj.permissions,
        name = options.hash.compare;
    if (permissions[name]){
        return options.fn(this);
    }
    return options.inverse(this);
});

完整代码

// The object in question
var obj = {
    "list": [{
        "id": 1,
            "name": "cms"
    }, {
        "id": 2,
            "name": "analytics"
    }, {
        "id": 3,
            "name": "coupons"
    }, {
        "id": 4,
            "name": "categories"
    }],
        "permissions": {
        "analytics": true,
            "categories": false,
            "cms": true,
            "coupons": false
    }
};

// Model for the Object
var HandlebarModel = Backbone.Model.extend({});

var handlebarModel = new HandlebarModel(obj);

// View that will render the template inside the table
var HandlebarView = Backbone.View.extend({
    el: $('#table'),
    initialize: function () {
        var source = $('#handlebar-template').html();
        this.template = Handlebars.compile(source);
    },
    render: function () {
        var $elem = $('tbody', this.$el);
        $elem.empty();
        $elem.append(this.template(this.model.toJSON()));
    }
});

Handlebars.registerHelper('ifCond', function (context, options) {
    console.log("this context " + this);
    console.log("name -" + options.hash.compare);
    console.log("Main Object - " + options.hash.obj);
    var permissions = options.hash.obj.permissions,
        name = options.hash.compare;
    if (permissions[name]){
        return options.fn(this);
    }
    return options.inverse(this);
});

var handlebarView = new HandlebarView({
    model: handlebarModel
});
handlebarView.render();

Check Fiddle