1

バックボーンとハンドルバーを 1 か月使用していますが、この問題があります。

モデルから取得した次のオブジェクトがあります。

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

ハンドルバーを使用して、相対許可値が次のように true の場合にボックスをチェックする方法を見つけようとしています。

{{#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);
});

誰かが私を助けてくれることを願っています!!

ありがとうございました!

4

1 に答える 1

2

そもそもヘルパーがなかったら、このようにテンプレートを作成していたでしょう。ここからスタート

ヘルパーなし

In the template you were trying to iterate over objects, which is not the right approach. You should leave that to the template helper to take care of that passing the correct context.

                       ---- 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) {

v1this context v2はhandlebar options オプションにマップされますundefined as no 3rd argumentはヘルパーで渡されました

したがって、テンプレートはこの形式になります

 {{#ifCond this obj=../this compare=this.name}} 
  • this - それぞれのコンテキスト (ループ内の現在のオブジェクト)
  • 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();

フィドルをチェック

于 2013-08-07T20:12:22.300 に答える