3

考虑这个带有指令“foo”的标记:

<div foo run="3"></div>
<div foo run="1"></div>
<div foo run="2"></div>

什么是使“foo”按指定顺序而不是从上到下(3、1、2)运行的好方法?我唯一能想到的就是跟踪已经运行的内容并在不正常的项目上返回 false,然后让 angular 尝试再次运行它们并重复直到它们全部完成。但这对我来说听起来很糟糕,因为它必须重复很多次...... Angular 有内置的东西可以使用吗?有没有理想的方法来处理这个问题?

4

2 回答 2

3

好的,这是我的解决方案,虽然它更像是一个模板。

Fiddle(检查控制台日志以查看结果)

我已将指令包装在foo指令中fooParent,如下所示:

<div foo-parent>
    <div foo run="3"></div>
    <div foo run="1"></div>
    <div foo run="2"></div>
</div>

fooParent指令的存在几乎可以做三件事:

  1. 向项目公开函数,foo以便将它们添加到一般列表中
  2. 维护一个列表foos,将在链接后进行排序
  3. 按指定的运行顺序处理每个foo

它看起来像这样:

app.directive('fooParent', function() {
    var foos = [];
    return {
        restrict: 'A',
        controller: ['$scope', '$element', '$attrs', '$transclude', function($scope, $element, $attrs, $transclude) {
            this.addFoo = function(runOrder, element) {
                foos.push({
                    run: 1*runOrder, // make sure run is an integer
                    element: element
                });
            };
        }],
        link: function(scope, element, attrs) {
            foos.sort(function(a, b) {
                return a.run - b.run;
            });
            // process all children here
            angular.forEach(foos, function(foo) {
                console.log(foo);
            });
        }
    };
});

foo看起来像:

app.directive('foo', function() {
    return {
        restrict: 'A',
        require: '^fooParent',
        link: function(scope, element, attrs, fooParent) {
            fooParent.addFoo(attrs.run, element);
        }
    };
});

显然,您必须找出处理远程加载内容的最佳方法,特别是如果您希望它被串行加载。您的foo指令将变得更加简化,因为加载和处理必须在fooParent.

于 2013-08-05T03:24:23.493 回答
3

感谢 OverZealous 启发了我的回答。在这里测试一下。http://jsbin.com/apumaj/21/edit

html(当然,指令输出将按此顺序显示)

<div foo run="7"></div>
<div foo run="3"></div>
<div foo run="1"></div>
<div foo run="2"></div>

并且指令(以“运行”顺序使指令输出加载)应该是不言自明的

app.directive('foo', function() {
  var foos = [];
  var foosLength = document.querySelectorAll('[foo]').length;
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          foos.push({element:element, run:attrs.run});
          if (foos.length === foosLength) {
             foos.sort(function(a, b) {
                return a.run - b.run;
            });
            console.log('ran in this order:');
            for (var i=0; i<foosLength; ++i) {
              //process foos!
              var foo = foos[i];
              console.log(foo.run);
              foo.element.text(foo.run);
            }
          }
        }
    };
});
于 2013-08-12T20:09:47.207 回答