如何使用ember-cli和handlebars 2.0.0制作条件助手?

时间:2015-02-04 18:11:31

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

我正在努力实现类似于以下形式或功能的东西:

{{#if has-permission "my_permission"}}
    // do some stuff here
{{else}}
    // fallback
{{/if}}

OR

{{#hasPermission session.user.permissions "my_permission"}}

我无法弄清楚这一点。我已阅读this但除了帮助内容或改变内容的助手之外,没有太多解释,例如{{render“something”}}

当我尝试使其成为条件时,我得到了这个:

registerBoundHelper-generated helpers do not support use with Handlebars blocks.

非常感谢任何帮助,谢谢!

编辑:

我的用户对象如下序列化:

{"User": {
    "id": 3,
    "name": "john doe",
    "permissions": [
        "view_projects",
        "edit_milestones",
        "change_widgets"
    ]}
}

我希望能够检查模板中的某个权限,而不是将特定权限绑定到计算属性。

PS Im使用ember 1.9.1,最新数据和把手2.0

2 个答案:

答案 0 :(得分:2)

根据docs,使用绑定帮助

是不可能的
  

绑定助手不支持使用Handlebars块或添加任何类型的子视图。

可以做的是将该逻辑推送到控制器,如下所示:

App.IndexController = Ember.ArrayController.extend({
  permission: "my_permission",
  hasPermission: function(){
    var permission = this.get('permission');

    return permission === 'my_permission';
  }.property('permission')
});

然后,在您的模板中,您可以执行以下操作:

<script type="text/x-handlebars" data-template-name="index">
  {{#if hasPermission }}

    <ul>
      {{#each item in model}}
        <li>{{item}}</li>
      {{/each}}
    </ul>

  {{ else }}
    // fallback
  {{/if}}
</script>

工作解决方案here

答案 1 :(得分:0)

您可以使用Ember的boundIf / unboundIf默认帮助程序来创建一个漂亮而强大的帮助程序来管理客户端的用户权限,最终得到如下内容:

{{#can 'createPost'}}
    <button {{action newBlogPost}}>New Post</button>
{{else}}
    You don't have permission to post
{{/can}}

{{#each post in controller}}
    <a {{action viewPost post href=true}}>{{post.title}}</a>
    {{#can 'editPost' post}}
        <button {{action editPost post}}>Edit</button>
    {{/can}}
{{/each}}

如果你看一下Ember&#39; source code,看看如果如何运作:

Ember.Handlebars.registerHelper('if', function(context, options) {
  Ember.assert("You must pass exactly one argument to the if helper", arguments.length === 2);
  Ember.assert("You must pass a block to the if helper", options.fn && options.fn !== Handlebars.VM.noop);

  return helpers.boundIf.call(options.contexts[0], context, options);
});

您可以看到它只进行了一些健全性检查,并将其移交给 boundIf

Ember.Handlebars.registerHelper('boundIf', function(property, fn) {
  var context = (fn.contexts && fn.contexts[0]) || this;
  var func = function(result) {
  if (Ember.typeOf(result) === 'array') {
      return get(result, 'length') !== 0;
    } else {
      return !!result;
    }
  };

  return bind.call(context, property, fn, true, func, func);
});

这反过来调用 bind ,它处理设置所有观察者并在属性更改时重新呈现。它构建的 func 的结果决定了是否显示内容。

因此,如果你创建一个调用 boundIf 的帮助器,并在一个对象上观察一些属性,它将为我们处理其余部分。

Handlebars.registerHelper('can', function(permissionName, property, options){

  // do magic here

  Ember.Handlebars.helpers.boundIf.call(someObject, "someProperty", options)
}); 

让我们假装神奇,看看会发生什么:

Handlebars.registerHelper('can', function(permissionName, property, options){

  var permission = Ember.Object.create({
    can: function(){
      return true;
    }.property()
  });

  Ember.Handlebars.helpers.boundIf.call(permission, "can", options)
});

嗯,这使内容隐藏起来。它似乎并没有在我们允许的情况下调用罐头。

如果我们回顾 boundIf ,那么我们可以看到它正在查看选项的上下文,只有在没有一组时才会回到这个

var context = (fn.contexts && fn.contexts[0]) || this;

我们可以通过修改我们传递给boundIf的选项的上下文来解决这个问题。 (我不确定这是否会引起问题,但它对我有用...... YMMV以及所有这些)。

Handlebars.registerHelper('can', function(permissionName, property, options){

  var permission = Ember.Object.create({
    can: function(){
      return true;
    }.property()
  });

  // wipe out contexts so boundIf uses `this` (the permission) as the context
  options.contexts = null;

  Ember.Handlebars.helpers.boundIf.call(permission, "can", options)
});

如果你将can的结果从true变为false,那么我们会看到我们的内容消失并重新出现,成功!

这个例子在Richard Livsey的这篇优秀post中详细介绍了