AngularJS过滤器导致IE8不呈现双向绑定

时间:2012-11-14 17:01:26

标签: javascript jquery angularjs

我对IE8有一个奇怪的问题,如果我尝试通过AngularJS的双向数据绑定在模板中呈现$scope变量,它将不会用适当的值替换{{child.name}}。这肯定与以下过滤器的低效率有关:

  filter('truncate', function() {
    return function(name) {
      // It's just easier to use jQuery here
      var windowWidth = $(window).width(),
          nameElement = $('a:contains("' + name + '")'),
          truncPnt = Math.floor(name.length * 0.9);

      while (nameElement.width() > windowWidth * 0.75 && truncPnt > 6) {

        truncPnt = Math.floor(truncPnt * 0.9);
        name = name.substring(0, truncPnt);
        nameElement.text(name + ' ...');
      }
      return name;
    }
  });

然后我将此过滤器与ng-repeat一起使用:

<a class="entity-name" href="{{child.url}}" title="{{child.name}}" ng-cloak>{{child.name|truncate}}</a>

总体目标是根据屏幕的宽度将传递到过滤器中的变量截断,用“...”替换任何截断的字符。我相当有信心这个过滤器是因为我有一个类似的函数在.resize() $(window)处理程序上被调用,如果我要使用IE8,并调整浏览器窗口的大小,它导致{{child.name}}呈现为正确的值,但仅限于我调整浏览器的大小。

更新


所以我已经摆脱了上面的过滤器,并用一个非常相似的指令替换它。这是我第一次尝试创建自定义指令,所以我相当肯定它可以做得更好,减去我目前似乎无法解决的明显缺陷。该指令如下:

.directive('truncate', function() {

  return {
    restrict: 'A',
    replace: true,
    template: '<a class="entity-name" href="{{child.url}}" title="{{child.name}}">{{child.display}}</a>',
    link: function(scope, element, attr) {
      var widthThreshold = $(element[0]).parent().parent().width() * 0.85;

      scope.$watch('child', function(val) {
        var elementWidth = $(element[0]).width(),
            characterCount = scope.child.name.length;

        while ($(element[0]).width() > widthThreshold || characterCount > 5) {
          characterCount--;
          scope.child.display = scope.child.name.substring(0, characterCount) + ' ...';
        }
      });
    }
  }
});

我将部分替换为简单:

<a truncate="child"></a>

与过滤器相反的差异如下(减去明显的过滤器与指令):

  1. windowWidth替换为widthThreshold,通过将jQuery的.parent()链接两次来识别该值(当获取父(x2)元素的宽度而不是窗口时,它实际上是更准确的值)。
  2. 为名为child的{​​{1}}添加了一个额外的密钥。这将是display的截断版本,用于显示,而不是使用jQuery的child.name,只使用截断的.text()进行渲染。
  3. child.name变为truncPnt(试图记住不要缩写变量)
  4. 现在的问题是jQuery冻结了浏览器,直到我杀了javascript(如果提示)。 Firefox可能会显示它,Chrome还没有挂起,虽然我还没有在IE中测试,但我认为比前者更糟糕。

    如何正确获取相关主元素之上的两个父项的值,并截断characterCount以使其不会包裹/延伸超过父div?

    更新2:


    我决定放弃主要基于DOM的计算的思想,而不是数学,考虑父div的宽度,字体大小,以及上帝知道什么的比例。我认真地插入一个公式,直到我得到的东西一直给出类似的结果,无论字体大小。媒体查询会影响相关字符串的字体大小CSS,所以我需要考虑到这一点,否则在不同字体大小之间截断字符串的长度会有一些显着差异:

    child.display

    有趣的是,我相信我完全回到了Brandon Tilley关于修改DOM与修改范围内属性的评论。现在我已将其更改为修改属性,它可能更适合在过滤器中使用?什么是决定是否应该在过滤器与指令中处理这种操作的决定性因素?

1 个答案:

答案 0 :(得分:1)

我参考文档:

<强>指令

  

指令是教授HTML新技巧的一种方式。在DOM编译期间,指令与HTML匹配并执行。这允许指令注册行为,或转换DOM。

http://docs.angularjs.org/guide/directive

过滤器

  

角度过滤器格式化数据以显示给用户。除格式化数据外,过滤器还可以修改DOM。这允许过滤器处理诸如有条件地将CSS样式应用于过滤输出之类的任务。

http://docs.angularjs.org/guide/dev_guide.templates.filters

我只会将过滤器用于更改数据格式而不是其他任何内容。说实话,我相信为您的目的使用过滤器是合适的。并且正如文档所说过滤器可以修改DOM我没有看到你应该使用指令的原因,过滤器似乎是你正在寻找的。 (除了错误可能会迫使你使用指令)