【问题标题】:Ember.js + JQuery-UI Tooltip - Tooltip does not reflect the model / controller changesEmber.js + JQuery-UI 工具提示 - 工具提示不反映模型/控制器更改
【发布时间】:2014-07-25 09:13:49
【问题描述】:

上下文

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

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

工具提示的内容是在控制器中计算出来的,它的功能基本上是根据上下文以各种方式连接字符串。然后它绑定到创建工具提示的<img> 的数据属性。当 View 准备好并触发 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>

视图:进程视图

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')
});

控制器:进程控制器

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:

将观察者中的“containers.@each”替换为“contentText”并添加日志记录。

【问题讨论】:

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


    【解决方案1】:

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

    您的工具提示库未观察到 data-caption 属性。这意味着,当您更新属性时,您必须明确告诉库也更新工具提示。因此,尽管您的属性更新得很好,但工具提示库实际上并没有关注这些更新。

    这可以通过在didInsertElement 中调用updateTooltip 来解决。但是,didInsertElement 仅在第一次插入元素时触发一次。内容改变时不调用。

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

    【讨论】:

    • 我遵循了你的想法,这听起来确实不错(我想知道为什么我一开始没有观察到这一点?!),并添加了一些日志记录。所以我确定updateTooltip 现在被调用了。尽管如此,刷新内容没有任何改进。好像是 JQuery-UI 刷新问题。
    【解决方案2】:

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

    感谢@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')
    });
    

    作为额外的好处,您现在可以避免将 data 属性用作缓冲区,尽管我不确定为什么。

    【讨论】:

      猜你喜欢
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2017-12-12
      • 1970-01-01
      • 1970-01-01
      • 2015-08-10
      • 1970-01-01
      相关资源
      最近更新 更多