提问者:小点点

如何使用enpe-cli和车把2.0.0制作条件助手?


我试图实现类似的形式或功能:

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

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

我想不通。我读过这篇文章,但除了渲染内容或更改内容的助手之外,没有太多解释,例如{{渲染“某物”}}

当我试图让它成为一个条件时,我得到了这个:

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

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

编辑:

My User对象被序列化如下:

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

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

PS我使用的是Eger 1.9.1,最新数据和车把2.0


共2个答案

匿名用户

根据文档,这对于绑定的帮助程序是不可能的

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

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

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>

这里的工作解决方案

匿名用户

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

{{#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的源代码并了解if的工作原理:

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

你可以看到它只做了一些健全性检查,并将手交给了边界:

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的结果决定了是否显示内容。

因此,如果您创建一个助手,该助手使用一些属性来观察对象,它将为我们处理其余的事情。

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

嗯,那就把内容隐藏起来了。似乎它没有在我们允许的情况下调用罐头。

如果我们回过头来看边界,那么我们可以看到它在查找选项的上下文,只有当没有一个集合时才会回到这个:

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

我们可以通过核化我们传递给边界的选项的上下文来解决这个问题。(我不确定这是否会引起问题,但对我有用… 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)
});

如果你摆弄的结果可以从真到假然后我们看到我们的内容消失和重新出现,成功!

这个例子将在Richard Livsey的这篇优秀文章中详细介绍