Ember.js Не обновляет DOM с наблюдаемым значением

#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