Вы можете использовать хелперы 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}}
Если вы посмотрите на исходный код и посмотрите, как работает 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);
});
Вы можете видеть, что он выполняет только некоторую проверку работоспособности и передает 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, который обрабатывает настройку всех наблюдателей и повторный рендеринг при изменении свойств. Результат создаваемой функции определяет, отображать контент или нет.
Поэтому, если вы создадите помощник, который вызывает 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, то увидим, что он просматривает контекст параметров и возвращается к this только в том случае, если нет ни одного набора:
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 с истинного на ложное, мы увидим, что наш контент исчезает и снова появляется, успех!
Этот пример более подробно описан в отличном сообщение Ричарда Ливси
person
Sávio Lucena
schedule
12.10.2015