registerBoundHelper:创建一个类似if的helper,通过json执行服务器端授权



javascript/coffeescript/ember.js/stackoverflow新手在这里!

我正在尝试创建一个类似if的助手,只有当对象上的操作从服务器授权时才显示内容。基本上我想从rails cancan gem的can?方法。我想这样写模板:

<h1>Viewing profile for {{email}}</h1>
<h2>Scores</h2>
{{#each score in scores}}
    <div class="summary">{{score.what}}  
        {{#can score action=destroy}}
            <a href="#" id="destroy">Destroyable</a>  
        {{/can}}
        {{#can score action=view}}
            <a href="#" id="view">Viewable</a>  
        {{/can}}
        {{#can score action=edit}}
            <a href="#" id="edit">Editable</a>  
        {{/can}}
    </div>
{{/each}}

can ember.js助手将用一个json请求查询服务器,看起来像这样:

<site>/api/v1/authorization.json?action=destroy&cName=Score&id=1

服务器将简单地返回HTTP状态码200或401,ember将根据状态码神奇地显示或隐藏内容。我必须这样做授权因为有一些角色- &基于对象的权限检查必须发生在服务器上,我不想在js中复制授权逻辑。

到目前为止,我已经使用了现成的if帮助器作为示例来创建以下自定义绑定帮助器(coffeescript)。
Ember.Handlebars.registerBoundHelper 'can', (object, options) ->
    permission = EmberDeviseExample.Authorization.create
        action: options.hash.action
        object: object
    permission.authorize()
    options.contexts = [permission]
    Ember.Handlebars.helpers.boundIf.call(permission, "can", options)

下面是User对象:

EmberDeviseExample.User = DS.Model.extend
  email:        DS.attr('string')
  scores:       DS.hasMany('EmberDeviseExample.Score')
EmberDeviseExample.store.adapter.serializer.map('EmberDeviseExample.User', {scores: {embedded: 'load'}})

这是授权对象:

EmberDeviseExample.Authorization = Ember.Object.extend
  action: ''
  object: null
  response: 401
  urlBase: ApiUrl.authorization_path
  can : (-> 
      return (this.get('response') == 200)
  ).property('response')
  authorize: ->
    # if object is an instance, include the id in the query params
    # otherwise, just include the class name
    obj = this.get('object')
    cName = obj.toString()
    id = null
    if Ember.typeOf(obj) == "instance"
      # cname looks something like "<namespace.name:embernumber>"
      # turn it into "name"
      cName = cName.split(':')[0].split('.')[1]
      id = obj.get('id')
    $.ajax 
       url : "#{this.get('urlBase')}.json"
       context : this
       type : 'GET'
       data : 
          action : this.get('action')
          cName : cName
          id : id
       complete : (data, textStatus, xhr) ->
          this.set('response', data.status)
    return this.get('can')

在服务器端,授权。json代码看起来像这样(rails 3)。我使用cancan gem来控制授权:

class AuthorizationsController < ApplicationController
  respond_to :json
  def show
    id     = params[:id]
    cName  = params[:cName]
    action = params[:action]
    object = cName.capitalize.constantize
    object = object.find(id) unless id.blank?
    authorized = can? action, object
    render status: (authorized ? 200 : 401), json: {}
  end
end

路线是这样的:

  scope "/api" do
    scope "/v1" do
      resource :authorization, only: [:show]
    end
  end

当然,我的应用程序中还有其他代码,如果你需要看到它,请告诉我。

当我删除#can帮助程序时,我看到了呈现的模板。当我添加#can助手回来,我得到一个javascript错误,在Chrome的消息是"Uncaught TypeError: Cannot read property '0' of null" @ ember.prod.js:2362.

有人知道如何构建一个接受对象和操作、运行服务器端授权检查和基于服务器结果显示/隐藏内容的帮助器吗?

刚刚看到你的问题,有点晚了,但也许我还能帮上忙。

虽然看到错误可能来自何处很复杂,但我看到您的预期实现中存在问题:您将自定义if helper绑定到属性'score',而观察响应中的变化的属性称为'can',作为helper…

最新更新