【问题标题】:Separating functions from Controllers to Directives将功能从控制器分离到指令
【发布时间】:2014-07-12 18:37:53
【问题描述】:

我了解 Angular 控制器应尽量不执行繁重的逻辑计算。

我的控制器中有一个函数,可以获取当前月份的 12 个月列表:

app.controller("MyController", function($scope) {

    $scope.getLast12Months = function () {

        var date = new Date();
        var months = [],
            monthNames = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
        for(var i = 0; i < 12; i++) {
            months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());

            // Subtract a month each time
            date.setMonth(date.getMonth() - 1);
        }
        $scope.months = months;

        return months;
    }


});

并通过以下方式显示在我的 HTML 中:

<th ng-repeat="months in getLast12Months()">{[{ months }]}</th>

我尝试通过以下方式将其放入指令中:

app.directive("ngGetLast12Months", function () {
return function ($scope) {

var date = new Date();
     var months = [],
            monthNames = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
        for(var i = 0; i < 12; i++) {
            months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());

            // Subtract a month each time
            date.setMonth(date.getMonth() - 1);
        }
        $scope.months = months;

        return months;
    }
});

在 HTML 中:

<th ng-get-last-12-months>{[{ months }]}</th>

我可以看到我的指令是通过 console.log 触发的,但输出显示为:

["2014 年 5 月","2014 年 4 月","2014 年 3 月","2014 年 2 月","2014 年 1 月","2013 年 12 月","2013 年 11 月","2013 年 10 月","2013 年 9 月"," 2013 年 8 月","2013 年 7 月","2013 年 6 月"]

而不是 ng-repeat 时尚显示为:

2014 年 5 月 2014 年 4 月 2014 年 3 月 2014 年 2 月 2014 年 12 月 2013 年 11 月 2013 年 10 月 2013 年 9 月 2013 年 8 月 2013 年 7 月 2013 年 6 月


基于工程师示例的更新

但是看到:错误:[$compile:tplrt]errors.angularjs.org/1.2.8/$compile/...

app.directive('ngGetLast12Months', function () {
return {
  replace: true,
  restrict: 'EA',
  template: '<th ng-repeat="month in months">{[{ month }]}</th>',
  link: function ($scope) {
    var date = new Date();
    var months = [], monthNames = [
        'Jan',
        'Feb',
        'Mar',
        'Apr',
        'May',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Oct',
        'Nov',
        'Dec'
      ];
    for (var i = 0; i < 12; i++) {
      months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());
      // Subtract a month each time
      date.setMonth(date.getMonth() - 1);
    }
    $scope.months = months;
    return months;
  }
};
});

【问题讨论】:

  • 你可能需要的是服务,而不是指令。
  • 我猜有问题
  • @Skeptor - 你是对的, 导致了那个错误,
    工作正常。但是,我需要它在 中。

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-repeat


【解决方案1】:

这是这个的 jsfiddle,http://jsfiddle.net/qF3KL/

这对我有用

html

<ng-get-last-12-months></ng-get-last-12-months>

js

.directive('ngGetLast12Months', function() {
    return {
        restrict: 'EA',
        template: '<th ng-repeat="month in months">{{month}}</th>',
        controller: function($scope) {
            var date = new Date();
            var months = [],
                monthNames = [
                    'Jan',
                    'Feb',
                    'Mar',
                    'Apr',
                    'May',
                    'Jun',
                    'Jul',
                    'Aug',
                    'Sep',
                    'Oct',
                    'Nov',
                    'Dec'
                ];
            for (var i = 0; i < 12; i++) {
                months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());
                // Subtract a month each time
                date.setMonth(date.getMonth() - 1);
            }
            $scope.months = months;
        }
    };
});

【讨论】:

  • 奇怪的是,我无法在本地工作
【解决方案2】:

像这样创建指令:

app.directive("ngGetLast12Months", function () {
    return {
        replace : true,
        restrict: 'EA',
        template: '<th ng-repeat="month in months">{[{ month }]}</th>',
        link: function ($scope) {
           //Your code which evaluates `months`
           $scope.months = months;
        }
    };
});

【讨论】:

  • 我在尝试上述操作时遇到以下错误:错误:[$compile:tplrt]errors.angularjs.org/1.2.8/$compile/… 已用您的指令示例的更完整版本更新了我的问题。
  • 我是否应该通过以下方式在我的 HTML 中调用它:
【解决方案3】:

我看不出这应该在指令中的原因。这是应该在服务中的代码。然后控制器可以在作用域上公开它,而 html 仍然可以使用 ng-repeat 来显示它。

您的指令给出不同响应的原因是它的工作方式与 ngRepeat 不同。 ngRepeat 使用内部 html 作为模板,并在您给它的循环的每次迭代中执行它。因此,它为数组中的每个元素克隆该位 DOM,然后插入该值。您的指令只是构建一个数组并直接输出该数组,因此您可以在 DOM 中获得它的 json 版本。

如果您真的想在指令中执行此操作,我会保持简单并使用指令的模板选项。这将允许您使用 ngRepeat 来迭代您在指令的链接函数中计算的值。

【讨论】:

  • 因为这个答案是在问题的“更新”部分之前给出的。如果你看,你可以看到他在 html 中执行&lt;th ng-get-last-12-months&gt;{[{ months }]}&lt;/th&gt;,在指令模板中的几个月内没有任何 ng-repeat(没有指令模板)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多