根据AngularJS指令中的输入值生成可变长度下拉列表

时间:2014-05-14 17:36:09

标签: angularjs angularjs-directive

我想提供一个页面选择指令,用于生成&#34;页面[ 1 ] x &#34;。下拉列表中的页数取决于传递给指令的值,因此它不能成为静态模板的一部分。我很难确定如何/在哪里生成<select><option>...</select>

我尝试通过以下方式尝试但未成功:

  • $observe
  • 中的$watch(和link
  • $scope中添加到controller的函数,该函数返回$compile(markup)($scope)这会导致错误Error: [$parse:isecdom] Referencing DOM nodes in Angular expressions is disallowed!
  • <select>元素的子指令(link $observe r似乎永远不会获得recordCount更新,无论是继承还是共享范围。)
  • 模板中的
  • ng-repeat

这是我目前的错误代码。

HTML

<x-pager
  record-count="{{recordCount}}"
  page-size="pageSize"
  page-number="pageNumber"
  set-page="selectPage(page)"
></x-pager>

JS

module.directive("pager", ["$compile",
    function ($compile)
    {
        return {
            template:   "<div class='pager' ng-show='recordCount > pageSize'>\
                           {{recordCount}} results\
                           <button>&laquo; Prev</button>\
                           page <select>\
                           <option>#</option>\
                           </select> of {{calcPages()}}\
                           <button>Next &raquo;</button>\
                         </div>",
            replace:    true,
            restrict:   "E",
            scope:      {
                recordCount: "@",
                pageSize:    "=",
                pageNumber:  "=",
                setPage:     "&"
            },
            link: function (scope, element, attrs)
            {
                /*
                 * We can't build the page selection dropdown until
                 * we know how many records we have. Register an
                 * observer to do this when recordCount changes.
                 */
                attrs.$observe("recordCount", function (recCnt)
                {
                    var html;
                    var pages;
                    var i;

                    if (angular.isDefined(recCnt)) {
                        html  = "<select>\n";
                        pages = Math.ceil(scope.recordCount / scope.pageSize);

                        for (i=1; i<=pages; i++) {
                            html += "  <option value='" + i + "'>" + i + "</option>\n";
                        }
                        html += "</select>";
                        console.log("generatePageSelect html", html);

                        html = $compile(html)(scope);

                        // add the template content
//                      angular.element("select.page-selector").html(html);
// template:            page <select class='page-selector'></select> of {{calcPages()}}\
                    }
                });
            },
            controller: function ($scope)
            {
                $scope.calcPages = function ()
                {
                    return Math.ceil($scope.recordCount / $scope.pageSize);
                };

                function genPagesArray ()
                {
                    var pages = $scope.calcPages();
                    var i;
                    var pagesArray = [];

                    for (i=0; i<pages; i++) {
                        pagesArray.push(i);
                    }

                    return pagesArray;
                }
                $scope.pagesArray = genPagesArray();
                console.log("$scope.pagesArray", $scope.pagesArray);


// template:    page {{generatePageSelect()}} of {{calcPages()}}\
                $scope.generatePageSelect = function ()
                {
                    var html  = "<select>\n";
                    var pages = $scope.calcPages();
                    var i;

                    for (i=1; i<=pages; i++) {
                        html += "  <option value='" + i + "'>" + i + "</option>\n";
                    }
                    html += "</select>";

                    return $compile(html)($scope);
                };
            }
        };
    }
]);

1 个答案:

答案 0 :(得分:1)

为了扩展我之前的评论,这里有一个指令(大部分)是你想做的。

angular.module('Test', []).controller('TestCtrl', function($scope) {
  $scope.pageSize = 10;
  $scope.pageNumber = 1;
  $scope.recordCount = 30;
}).directive("pager", function () {
  return {
    template: '<div class="pager" ng-show="recordCount > pageSize">\
      {{recordCount}} results\
      <button ng-click="pageNumber = pageNumber - 1" ng-disabled="pageNumber <= 1">&laquo; Prev</button>\
      page <select ng-model="pageNumber" ng-options="i for i in pages"></select> of {{totalPages}}\
      <button ng-click="pageNumber = pageNumber + 1" ng-disabled="pageNumber >= totalPages">Next &raquo;</button>\
    </div>',
    replace: true,
    restrict: "E",
    scope:      {
      recordCount: "@",
      pageSize:    "=",
      pageNumber:  "=",
      setPage:     "&"
    },
    link: function (scope, element, attrs) {
      attrs.$observe("recordCount", function (count) {
        if (angular.isDefined(count)) {
          scope.recordCount = parseInt(count);
          var i;
          scope.totalPages = Math.ceil(scope.recordCount / scope.pageSize);

          scope.pages = [];
          for (i=1; i<=scope.totalPages; i++) {
            scope.pages.push(i);
          }
        }
      });
    }
  }
});

Plunkr here.