#javascript #ember.js
#javascript #ember.js
Вопрос:
У меня есть Ember.js приложение с этим javascript:
var App = Ember.Application.create({
LOG_TRANSITIONS: false,
LOG_TRANSITIONS_INTERNAL: false,
LOG_VIEW_LOOKUPS: false,
});
App.Router.map(function() {
this.route('messageviewer', { path: '/message_viewer' });
});
App.Message = Ember.Object.extend({
message: {},
topic: '',
});
App.Message.reopenClass({
messages: {},
topics: [],
getAllMessagesList: function(){
var ret = [];
for(var i = 0; i < this.topics.length; i ){
ret = ret.concat(this.messages[this.topics[i]]);
}
return ret;
}.observes('App.Message.messages');
addMessage: function(message){
console.log(message);
if(!(message.topic in this.topics)){
this.topics.push(message.topic);
this.messages[message.topic] = [];
}
this.messages[message.topic].push(App.Message.create({
message: message,
topic: message.topic,
}));
},
});
App.MessageviewerRoute = Ember.Route.extend({
model: function(){
return App.Message.getAllMessagesList();
},
});
App.MessageviewerView = Ember.View.extend({
templateName: 'messageViewer',
didInsertElement: function(){
Ember.run.scheduleOnce('afterRender', this, fayeStartListening);
},
willDestroyElement: function(){
fayeStopListening();
},
});
Вот шаблон, который идет с представлением:
<div class="row">
<div id="filter-panel" class="col-md-3">
<h2>Topics</h2>
<div class="btn-group-vertical full-width" data-toggle="buttons">
<label class="btn btn-primary">
<input type="radio" name="topics">Test 1</input>
</label>
<label class="btn btn-primary">
<input type="radio" name="topics">Test 2</input>
</label>
</div>
{{#with content}}
{{#each}}
{{!-- Make a topic list for testing --}}
<h4>{{topic}}</h4>
{{/each}}
{{/with}}
</div>
</div>
Также запущен клиент Faye, и он подписан на канал, который получает довольно много сообщений в секунду. В своей подписке он вызывает App.Message.addMessage(message);
, и я знаю, что это работает на основе вывода журнала в addMessage. Кроме того, я подтвердил в инспекторе Ember, что модель обновляется. Однако DOM не меняется. Если я переключусь на другой маршрут и вернусь, в списке будут показаны все элементы, собранные во время прослушивания клиентом Faye. Я не совсем уверен, что я должен сделать, чтобы список обновлялся динамически.
Я заметил, что если я делаю {{#each in content}}
или {{#each in model.content}}
вместо {{#with}}
блока, то я получаю сообщение об ошибке «Не удается установить свойство’dataSourceBinding’ undefined». Кроме того, я видел, как люди предлагали использовать this.set(..., ...)
, но в моем случае это не сработает, потому что мне пришлось бы вызывать его из статического контекста, поэтому он не определен.
Кто-нибудь знает, как убедить Ember обновлять DOM в режиме реального времени?
Комментарии:
1. Я также не уверен, что вы хотите использовать observes вместо property , но я нахожусь на своем телефоне, и это боль, которую вы действительно читаете.
2. Что ж, это интересно — изменение
getAllMessagesList
observes на свойство приводит к тому, что функция не существует (существует ошибка TypeError, которую вы не можете вызвать undefined в модели).
Ответ №1:
Используйте pushObject или AddObject вместо push, это аналогично установщику для массивов.
Поскольку вы пытаетесь просмотреть объект messages, вы смотрите, изменяется ли ссылка, а не изменилось ли что-либо под ней.
http://emberjs.com/api/classes/Ember .Наблюдаемый.html#method_notifyPropertyChange
Комментарии:
1. Я попробовал оба из них — изменение
push(...)
наpushObject(...)
и наaddObject(...)
, и ни один из них не имел никакого эффекта.2. Ах, вы пытаетесь наблюдать за объектом, а не за каким-либо конкретным свойством, что означает, что он никогда не будет пересчитан
3. Вам нужно будет переключиться на массив и просмотреть массив или вручную запустить notifyPropertyChange