Функция IronRouter, расширяющая данные на контроллере маршрута
Есть ли способ расширить параметр data
при использовании IronRouter и RouteController
. Похоже, что он переопределяется, когда я наследую суперконтроллер, дочерний контроллер не расширяет определенные свойства data
, У меня были аналогичные проблемы с параметром yieldTemplates
на маршруте и использовалось обходное решение (underscore _extends), но в этом случае он не работал:
ApplicationController = RouteController.extend({
data: function(){
return {
user: Meteor.user()
}
}
});
ChildController = ApplicationController.extend({
data: function(){
return {
// I expect to inherit Meteor.User ?????
someData: {}
}
}
});
EDIT:
После использования функции underscore
и extend
для наследования функции прототипа я все еще не могу наследовать определение route
, которое использует ChildController
this.route('someRoute', {
template: 'task_template',
//tasks is not available on the template
data: function () {
var base = ChildController.data.call(this);
console.log(base);
return _.extend(base, {
tasks: Tasks.find({state: 'Open'})
});
});
Ответы
Ответ 1
Я использую что-то похожее на это в производственном приложении:
Router.route('/test/:testparam', {
name: 'test',
controller: 'ChildController'
});
ParentController = RouteController.extend({
data: function() {
console.log('child params: ', this.params);
return {
foo: 'bar'
};
}
});
ChildController = ParentController.extend({
data: function() {
var data = ChildController.__super__.data.call(this);
console.log(data);
return data;
}
});
Использование __super__
похоже на трюк!
Вы можете использовать _.extend для расширения данных (http://underscorejs.org/#extend)
Ответ 2
Чтобы добавить к выбранному ответу, обратите внимание, что если вы используете Coffeescript, следующий результат даст тот же результат:
class @ChildController extends ParentController
data: -> super()
# or if you want to add to it:
data: ->
_.extend super(), { extraThing: 'some value' }
Ответ 3
Я думаю, что _.extends
должен работать и в этом случае:
ChildController = ApplicationController.extend({
data: function() {
var base = ApplicationController.data.call(this);
return _.extends(base, {
someData: {},
});
}
});
Ответ 4
Другим вариантом, который может достичь того же результата, является определение метода на вашем родительском контроллере, а затем вызов его с помощью супер без расширения чего-либо. Это немного больше работает для каждого контроллера, но проще применять задним числом. Также он делает метод необязательным для вашего дочернего контроллера, а не по умолчанию.
ApplicationController = RouteController.extend({
waitOn: function() {
return [Meteor.subscribe('customUserPublish')];
},
GetProfileWithEmail: function(){
var user = Meteor.user();
var profile = user.profile;
profile.email = user.emails[0].address;
return profile;
}
});
ProfileController = ApplicationController.extend({
waitOn: function() {
return [Meteor.subscribe('anotherCollectionPublish')];
},
data: function(){
return {
profile: function(){
var profile = ApplicationController.__super__.GetProfileWithEmail.call(this);
console.log('profile from super', profile);
return profile;
}
}
}
});
Помните, что вам также необходимо подписаться на опубликованную коллекцию, и я считаю, что вам нужно использовать параметр waitOn array, чтобы он правильно объединил подтипы (по общему признанию, я всегда использую формат массива, поэтому YMMV). Вы можете получить доступ к данным в своем шаблоне, используя {{#with profile}}... {{/with}}, или если вы возвращаете массив объектов, используйте {{#each profile}}... {{/each }}.