簡體   English   中英

具有Transclusion和分塊數據的AngularJS指令

[英]AngularJS Directive with Transclusion and chunking data

我正在嘗試重新創建一個我在AngularJS中創建的jQuery插件作為指令。 我在翻譯方面遇到了一些問題。

jQuery Widget插件: http//plnkr.co/edit/xxZIb2DyAere7pBY6qm7?p = preview

AngularJS指令: http ://plnkr.co/edit/N6f5H8oZkpNy5jbVQPgj? p = preview

-

我有一系列用戶喜歡:

[
    { name: 'intellix' }, { name: 'and' }, { name: 'konoro' }, { name: 'kingdom' }, { name: 'are' }, { name: 'awesome' },{ name: 'really!' }
]

我的jQuery小部件將數據分塊,因此它們分為3行並滑動它們......數據被轉換成塊並放入它們自己的容器中,如:

[
    [
        { name: 'intellix' }, { name: 'and' }, { name: 'konoro' }
    ], 
    [
        { name: 'kingdom' }, { name: 'are' }, { name: 'awesome' }
    ],
    [
        { name: 'really!' }
    ]
]

作為一名設計師或使用這個小部件的任何人,他們不應該自己將它們分塊,這就是小部件/指令應該是什么,你應該能夠擁有自己的HTML ......類似於:

<flicker delay="1000">
    <flicker-row ng-repeat="user in users">
        <p>User: {{user.name}}</p>
    </flicker-row>
</flicker>

我想要的結果是:

<flicker delay="1000">
    <div class="container">
        <flicker-row>
            <p>User: intellix</p>
        </flicker-row>
        <flicker-row>
            <p>User: and</p>
        </flicker-row>
        <flicker-row>
            <p>User: konoro</p>
        </flicker-row>
    </div>
    <div class="container">
        <flicker-row>
            <p>User: kingdom</p>
        </flicker-row>
        <flicker-row>
            <p>User: are</p>
        </flicker-row>
        <flicker-row>
            <p>User: awesome</p>
        </flicker-row>
    </div>
    <div class="container">
        <flicker-row>
            <p>User: really</p>
        </flicker-row>
    </div>
</flicker>

ngTransclude只是將整個HTML循環遍歷並將其置於閃爍指令的模板中。 我想在該指令中創建3個塊,然后循環遍歷這些塊,將HTML打印到這3個容器中。

如何轉換創建范圍,但不是只將整個結果轉儲到模板中?

我試圖在我的控制器中預先將數據分塊並有2個控制器...但是在我的閃爍行指令中,項目還沒有循環,所以我無法處理它們

<flicker delay="1000">
    <flicker-row ng-repeat="users in userChunks">
        <div class="item" ng-repeat="user in users">
            <p>{{user.name}}</p>
        </div>
    </flicker-row>
</flicker>

使用自定義Transclusion檢查我的解決方案。

DEMO

JS:

.directive('flicker', function() {
  return {
    restrict: 'E',
    scope: {
      collection:"=",
      item:"@"
    },
    transclude: true,
    replace:true, //I don't want redundant tag after compilation
    template: '<div></div>',//simple template for demonstration.

    compile: function (element, attr, linker) {//the linker parameter is for custom translusion

        return function (scope, element, attr) {
          scope.$watchCollection("collection", function(collection){

            var children = element.children();

            //check if there are already elements, if so remove its scope
            for (i = 0; i < children.length; i++){           
              children.eq(i).children().eq(0).scope().$destroy();
            };

            element.html("");//clear old content

            var chunks = collection.chunk(3);//hardcode 3 for demonstration, we could pass this to the directive's scope by exposing 1 more property in the scope.

            for (i = 0; i < chunks.length; i++) {
              var div = angular.element("<div class='container'>");
              element.append(div);

              for (j=0;j<chunks[i].length;j++){
            // create a new scope for every element in the collection.
                var childScope = scope.$new();
                // pass the current element of the collection into that scope
                childScope[scope.item] = chunks[i][j];

                  linker(childScope, function(clone){
                    // clone the transcluded element, passing in the new scope.
                       div.append(clone); // add to DOM
                  });
                }
            }
          });

        };
     }
  };
})

HTML:

<flicker item="user" collection="users" >
    <flicker-row>
        <p>U: {{user.name}}</p>
    </flicker-row>
</flicker>

閃爍指令有2個參數:

  • collection:用於呈現子項的集合。
  • item:一個字符串,表示綁定的屬性名稱。 在這種情況下,我使用user

IMO,在這種情況下,范圍管理應該由<flicker>負責,因為閃爍決定了如何分塊數據。 <flicker>的內部html只是動態生成的模板。

如果你需要使用像ng-repeat這樣的語法。 試試這個:

DEMO

HTML:

<flicker repeat="user in users" >
      <flicker-row>
        <p>U: {{user.name}}</p>
      </flicker-row>
    </flicker>

JS:

.directive('flicker', function() {
  return {
    restrict: 'E',

    transclude: true,
    replace:true,
    template: '<div></div>',

    compile: function (element, attr, linker) {
        return function (scope, element, attr) {
           var match = attr.repeat.match(/^\s*(.+)\s+in\s+(.*?)\s*$/), //parse the syntax string
            itemString = match[1],
            collectionString = match[2];

          scope.$watchCollection(collectionString, function(collection){

            var children = element.children();

            //check if there are already elements, if so remove its scope
            for (i = 0; i < children.length; i++){           
              children.eq(i).children().eq(0).scope().$destroy();
            };

            element.html("");//clear old content

            var chunks = collection.chunk(3);

            for (i = 0; i < chunks.length; i++) {
              var div = angular.element("<div class='container'>");
              element.append(div);

              for (j=0;j<chunks[i].length;j++){
            // create a new scope for every element in the collection.
                var childScope = scope.$new();
                // pass the current element of the collection into that scope
                childScope[itemString] = chunks[i][j];

                  linker(childScope, function(clone){
                    // clone the transcluded element, passing in the new scope.
                       div.append(clone); // add to DOM
                  });
                }
            }
          });

        };
     }
  };
})

您可以進行“手動”轉換。

看看我的示例: 自定義轉換示例

我剛試過不再發明輪子所以我在我的指令中使用了flicker.js和jquery。 結果是一個易於使用的指令。 希望有用。 演示頁面

在視圖中

 <flicker users="users"></flicker>

閃爍的模板:

<section class="flicker">
    <article ng-repeat="users in chunks" class="row">
        <div class="innerSlider">
            <div class="item" ng-repeat="user in users">
                <p>U: {{user.name}}</p>
            </div>
        </div>
    </article>
</section>

腳本:

 Array.prototype.chunk = function (chunkSize) {
        var array = this;
        return [].concat.apply([],
          array.map(function (elem, i) {
              return i % chunkSize ? [] : [array.slice(i, i + chunkSize)];
          })
        );
    };

    angular.module('flicker', [])
    .controller('FlickerCtrl', function ($scope) {
        $scope.users = [
          { name: 'intellix' }, { name: 'are' }, { name: 'konoro' }, { name: 'kingdom' }, { name: 'are' }, { name: 'awesome' }, { name: 'really!' }
        ];
    })
    .directive('flicker', function ($timeout) {
        return {
            restrict: 'E',
            replace: false,
            scope: {
                users: '='
            },
            templateUrl: 'flicker-template.html',
            link: function (scope, element, attrs) {
                scope.chunks = scope.users.chunk(3);

                $timeout(function () { $('.flicker', element).flicker({}); });

            }
        };
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM