角指令滚动到某一项目 [英] Angular directive to scroll to a given item

查看:118
本文介绍了角指令滚动到某一项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这是在我的控制器中定义的范围变量$ scope.first_unread_id。在我的模板,我有:

 < D​​IV ID =项目>
  < UL类=标准清单>
    <李NG重复=中的项项滚动到ID =first_unread_id>
    <跨度类=内容> {{item.content}}< / SPAN>
    < /李>
  < / UL>
< / DIV>

和我的指令如下:

  angular.module('ScrollToId',[])。
指令(scrollToId',函数(){
  返回功能(范围,元素,属性){
    。VAR ID = $范围父[属性[scrollToId]];
    如果(ID === scope.item.id){
      的setTimeout(函数(){
        window.scrollTo(0,元素[0] .offsetTop - 100)
      },20);
    }
  }});

它的工作原理,但是,有两个问题:


  1. 有没有收到first_unread_id关控制器范围为大于询问范围。$母公司直接的更好的办法?这似乎有点恶心。我希望我能传递通过视图来直接作为参数W / O不必重复有史以来li元素上。


  2. 有没有更好的办法避免的setTimeout的需要()调用?没有它,它工作的有时的 - 我想是由于布局的时间差。我明白,我用的是定义一个链接函数的语法 - 但它不是我清楚,如果这是一个pre或链接后默认 - 如果,即使是我的问题事项

    <。 / LI>

解决方案

  1. 您应该不需要范围$父 - 因为它会继承父范围值,当它在父范围内变化,它会向下传递

  2. 默认是一个链接后的功能。你有一些图片或装载的东西,这将使初始加载后的页面布局变化很快?你有没有尝试过的setTimeout没有时间就可以了,如的setTimeout(函数(){})?这将确保这会去一后一切就完成了。

  3. 我也想改变你的指令的逻辑有点使其更加通用。我会让它滚动的元素,如果给定的条件为真。

下面是那些3的变化:

HTML

 &LT; D​​IV ID =项目&GT;
  &LT; UL类=标准清单&GT;
    &LT;李NG重复=中的项项滚动如果=item.id == first_unread_id&GT;
      &LT;跨度类=内容&GT; {{item.content}}&LT; / SPAN&GT;
    &LT; /李&GT;
  &LT; / UL&GT;
&LT; / DIV&GT;

JS:

  app.directive('scrollIf',函数(){
  返回功能(范围,元素,属性){
    的setTimeout(函数(){
      如果(范围。$的eval(attributes.scrollIf)){
        window.scrollTo(0,元素[0] .offsetTop - 100)
      }
    });
  }
});

I have a scope variable $scope.first_unread_id which is defined in my controller. In my template, I have:

<div id="items" >
  <ul class="standard-list">
    <li ng-repeat="item in items" scroll-to-id="first_unread_id">
    <span class="content">{{ item.content }}</span>
    </li>
  </ul>
</div>

and my directive looks like:

angular.module('ScrollToId', []).
directive('scrollToId', function () {
  return function (scope, element, attributes) {
    var id = scope.$parent[attributes["scrollToId"]];
    if (id === scope.item.id) {
      setTimeout(function () {
        window.scrollTo(0, element[0].offsetTop - 100)
      }, 20);
    }
  }

});

it works, however, two questions:

  1. Is there a better way of getting the "first_unread_id" off the controller scope into the direct than interrogating scope.$parent? This seems a bit 'icky'. I was hoping I could pass that through the view to the direct as a parameter w/o having to repeat that on ever li element.

  2. Is there a better way to avoid the need of the setTimeout() call? Without it, it works sometimes - I imagine due to difference in timing of layout. I understand the syntax I have used is defining a link function - but it isn't clear to me if that is a pre or post-link by default - and if that even matters for my issue.

解决方案

  1. You shouldn't need the scope.$parent - since it will inherit the value from the parent scope, and when it changes in the parent scope it will be passed down.
  2. The default is a post-link function. Do you have some images or something loading that would make the page layout change shortly after initial load? Have you tried a setTimeout with no time on it, eg setTimeout(function(){})? This would make sure this would go 'one after' everything else is done.
  3. I would also change the logic of your directive a bit to make it more general. I would make it scroll to the element if a given condition is true.

Here are those 3 changes:

html:

<div id="items" >
  <ul class="standard-list">
    <li ng-repeat="item in items" scroll-if="item.id == first_unread_id">
      <span class="content">{{ item.content }}</span>
    </li>
  </ul>
</div>

JS:

app.directive('scrollIf', function () {
  return function (scope, element, attributes) {
    setTimeout(function () {
      if (scope.$eval(attributes.scrollIf)) {
        window.scrollTo(0, element[0].offsetTop - 100)
      }
    });
  }
});

这篇关于角指令滚动到某一项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆