Ember.js + JQuery-UI工具提示 - 工具提示不反映模型/控制器的更改

时间:2014-07-25 09:13:50

标签: jquery-ui ember.js tooltip refresh observer-pattern

上下文

我有一个小的Ember应用程序,除其他外,它显示了许多连接的用户,并且当悬停页面的一个元素时,他们的名字作为列表。

总而言之,它运作良好。应用程序每两分钟从REST端点提取数据,因为后端不允许推送数据。

工具提示的内容在Controller中计算,其功能基本上根据上下文以各种方式连接字符串。然后它绑定到创建工具提示的<img>的数据属性。当视图准备就绪并触发didInsertElement时,将根据此data-bindattr值生成工具提示(如果需要)。

问题

从后端提取新数据时,除工具提示内容外,所有内容都会相应更新。 (浏览页面的DOM时,data-bindattr值也会更新。)

什么可能导致工具提示无法刷新?这是JQuery-UI不再计算它的情况吗?

一些代码

在应用程序控制器中刷新代码:

Monitor.ApplicationController = Ember.ArrayController.extend({
  itemController: 'process',
  sortProperties: ['name'],
  sortAscending: true,
  intervalId: undefined,
  startRefreshing: function() {
    var self = this;
    if (self.get('intervalId')) {
      return;
    }
    self.set( 'intervalId', setInterval(function() {
      self.store.find('process');
    }, 120000 ));
  }
});

查看:Process.hbs

<div {{bind-attr class=":inline inactive:inactive"}}>
    <img {{bind-attr src=icon}} {{bind-attr data-caption=contentText}} class="caption" />
    <div class="counter">{{nbUsers}}</div>
</div>

查看:ProcessView

Monitor.ProcessView = Ember.View.extend({
  // (...) Various stuff.
  didInsertElement: function() {
    this.updateTooltip();
  },
  updateTooltip: function() {  
    console.log('Inside updateTooltip!');
    if (!this.$()) {return;}  
    if (this.get('controller').get('inactive')) {
        this.$().tooltip({items: '.caption', disabled: true});
        return;
    }
    this.$().tooltip({
        items: '.caption',
        tooltipClass: 'tooltip',
        content: function() {
            return $(this).data('caption');
        },
        position: {
            my: 'left+15px center',
            at: 'right center',
            collision: 'flip'
        },
        show: false,
        hide: false
    });
  }.observes('controller.inactive', 'controller.contentText')
});

Controller:ProcessController

Monitor.ProcessController = Ember.ObjectController.extend({
  contentText: function() {
    var tooltipContent = '';
    this.get('containers').forEach(function(container) {
    // Do a lot of things to tooltipContent involving: 
    // container.get('name')
    // container.get('text')
    // container.get('size')
    // container.get('nbUsers')
    // The data-bindattr value refreshes correctly so I cut this out for readability.
    return tooltipContent;
  }.property('name', 'containers.@each')
});

编辑1:

取代了容器。@ each&#39;通过&#39; contentText&#39;在观察者中并添加了记录。

2 个答案:

答案 0 :(得分:2)

以下是我认为正在发生的事情:

您的工具提示库未遵守data-caption属性。这意味着,当您更新属性时,您必须明确告诉库更新工具提示。因此,尽管您的属性正在更新,但工具提示库实际上并没有关注这些更新。

可以通过在updateTooltip中调用didInsertElement来解决此问题。但是,didInsertElement仅在首次插入元素时触发一次。当内容发生变化时,不会调用它。

我认为这两件事合起来会导致你的问题。我认为您需要做的就是让updateTooltip同时观察controller.contextText属性。然后在文本更新时调用它。

答案 1 :(得分:1)

事实证明我的代码声明并初始化了工具提示,但一旦完成,您就无法以相同的方式更改内容。此外,它还增加了不必要的计算。

感谢@ GJK的答案和that question,我发现了发生了什么。事实证明,您需要设置工具提示的内容以刷新它,而不是重新创建它。

以下是Ember整合的工作代码:

Monitor.ProcessView = Ember.View.extend({
  // Other stuff
  didInsertElement: function() {
    this.initTooltip();
  },
  initTooltip: function() {  
    if (!this.$()) {return;}  
    if (this.get('controller').get('inactive')) {
        this.$().tooltip({items: '.caption', disabled: true});
        return;
    }
    this.$().tooltip({
        items: '.caption',
        tooltipClass: 'tooltip',
        content: function() {
            return $(this).data('caption');
        },
        position: {
            my: 'left+15px center',
            at: 'right center',
            collision: 'flip'
        },
        show: false,
        hide: false
    });
  },
  updateTooltip: function() {
    if (!this.$()) {return;}  
    if (this.get('controller').get('inactive')) {
        this.$().tooltip({items: '.caption', disabled: true});
        return;
    }
    content = this.get('controller').get('contentText');
    this.$().tooltip("option", "content", content);
  }.observes('controller.contentText')
});

作为额外的奖励,您现在可以避免将数据属性用作缓冲区,但我不确定原因。