在angularjs过滤器中添加watch()

时间:2014-03-13 08:26:01

标签: angularjs filter watch angularjs-filter

我正在尝试创建一个过滤器,可以在调整浏览器大小时实时转换字符串并点击媒体查询断点。

我只想:

  • 当min-width< = 200px
  • 时显示"string.short"
  • 当min-width>时显示"string.long" 200像素
  • 使其具有通用性和可重用性(不希望将代码放入控制器中)
  • 不能使用指令因为,我将填写title / value / alt属性
  • 之类的东西

到目前为止,它正在加载时工作(没有调整大小),但我想添加浏览器调整大小检测以在用户调整浏览器大小时调整标签。

HTML:

<input value="{{ 'string' | responsivize}}" />

过滤:

angular.module('filters.responsivize', [])

.filter('responsivize', [function() {
    return function(key) {

        var showShort = function() {
            return Modernizr && !Modernizr.mq('only all and (min-width: 768px)');
        };

        //TODO: add any way to wath this in real time ?
        //$rootScope.$watch(showShort, function () {});
        //jQuery(window).resize(function() {});

        return key.concat(showShort() ? '.short' : '.long');
    };
}]);

(部分)工作jsfiddle http://jsfiddle.net/2Q8eL/2/

1 个答案:

答案 0 :(得分:1)

只有在Angular检测到要过滤的值发生更改后,才应使用过滤器格式化/过滤数据。你当然可以将$ rootScope注入你的过滤器并调用$ rootScope。$ apply()来触发Angular再次调用过滤器,但这对其他开发人员来说会有点混乱。

我说你有两种选择。一种是为你的app模块添加一个运行块,在你可以调用的$ rootScope上添加一个方法,它监听调整大小事件并调用$ rootScope。$ apply()。

所以你要这样做:

<input value="{{responsivize('string')}}" />

另一种选择不是把它作为一个运行块,而是制作一个指令,它仍然将响应方法放在$ rootScope上。您可以为该指令命名并将其添加到<body>

基本上是这样的:

angular.module('app')
  .directive('responsivize', function($rootScope) {
    return {
      restrict: 'A',
      link: function(scope, elm, attr){
        var showShort = Modernizr && !Modernizr.mq('only all and (min-width: 768px)');

        jQuery(window).resize(function() {
          var showShort = Modernizr && !Modernizr.mq('only all and (min-width: 768px)');
          $rootScope.$apply();
        });

        $rootScope.responsivize = function(key) {
          return key.concat(showShort ? '.short' : '.long');
        }
      }
    };
  });

HTML:

<body responsivize>
  ...
</body>

这样它就与该指令隔离,你可以重用它。请注意,窗口调整大小事件可能会激活很多次,因此您可能希望限制调用$ rootScope的次数。$ apply()。

将其作为方法而不是过滤器的好处是,调用该方法的代码可以根据需要自由格式化/使用返回值。