Ошибка Tracker afterFlush: невозможно прочитать значение свойства из контекста данных в обратном вызове, отображаемом шаблоном
Я делаю простое приложение Meteor, которое может перенаправлять на страницу, когда пользователь нажимает на ссылку. На шаблоне 'redirect' я пытаюсь получить значение свойства 'url' из экземпляра шаблона. Но я получаю правильное значение только при первом нажатии на ссылку. Когда я нажимаю F5, чтобы обновить страницу перенаправления, я получаю сообщение об ошибке:
Исключение из функции afterFlush от Tracker: невозможно прочитать свойство 'url' с нулевым значением. TypeError: невозможно прочитать свойство 'url' с нулевым значением в Template.redirect.rendered ( http://localhost:3000/client/redirect.js?abbe5acdbab2c487f7aa42f0d68cf612f472683b:2:17) в нуле.
На это указывает debug.js: (строка 2)
if (allArgumentsOfTypeString)
console.log.apply(console, [Array.prototype.join.call(arguments, " ")]);
else
console.log.apply(console, arguments);
} else if (typeof Function.prototype.bind === "function") {
// IE9
var log = Function.prototype.bind.call(console.log, console);
log.apply(console, arguments);
} else {
// IE8
Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
}
Можете ли вы сказать мне, почему я не могу прочитать значение свойства 'url' из контекста данных шаблона в обратном вызове шаблона?
Это мой код (для более подробной информации, вы можете посетить мой репо):
HTML:
<template name="layout">
{{>yield}}
</template>
<template name="home">
<div id="input">
<input type="text" id="url">
<input type="text" id="description">
<button id="add">Add</button>
</div>
<div id="output">
{{#each urls}}
{{>urlItem}}
{{/each}}
</div>
</template>
<template name="redirect">
<h3>Redirecting to new...{{url}}</h3>
</template>
<template name="urlItem">
<p><a href="{{pathFor 'redirect'}}">
<strong>{{url}}: </strong>
</a>{{des}}</p>
</template>
home.js
Template.home.helpers({
urls: function(){
return UrlCollection.find();
}
});
Template.home.events({
'click #add': function() {
var urlItem = {
url: $('#url').val(),
des: $('#description').val()
};
Meteor.call('urlInsert', urlItem);
}
});
redirect.js
Template.redirect.rendered = function() {
if ( this.data.url ) {
console.log('New location: '+ this.data.url);
} else {
console.log('No where');
}
}
Template.redirect.helpers({
url: function() {
return this.url;
}
});
router.js
Router.configure({
layoutTemplate: 'layout'
})
Router.route('/', {
name: 'home',
waitOn: function() {
Meteor.subscribe('getUrl');
}
});
Router.route('/redirect/:_id', {
name: 'redirect',
waitOn: function() {
Meteor.subscribe('getUrl', this.params._id);
},
data: function() {
return UrlCollection.findOne({_id: this.params._id});
}
});
publication.js
Meteor.publish('getUrl', function(_id) {
if ( _id ) {
return UrlCollection.find({_id: _id});
} else {
return UrlCollection.find();
}
});
2 ответа
С помощью моего коллеги я могу решить проблему. Моя проблема связана с неправильным синтаксисом Meteor.subscribe. В моем коде я забываю "return" в функции waitOn. Это заставит Метеор не знать, когда данные будут полностью загружены. Вот правильный синтаксис:
waitOn: function() {
return Meteor.subscribe('getUrl', this.params._id);
}
Добавь это
Router.route('/redirect/:_id', {
name: 'redirect',
waitOn: function() {
Meteor.subscribe('getUrl', this.params._id);
},
data: function() {
if(this.ready()){
return UrlCollection.findOne({_id: this.params._id});
}else{
console.log("Not yet");
}
}
});
Скажи мне, если работает.