Angular $ interval不是函数问题

时间:2017-02-27 14:19:39

标签: javascript angularjs directive clock

我知道你可能会将此标记为重复但没有任何兄弟主题无法解决我的问题,所以这是我简单的日期倒计时指令:

class Clock {
    constructor() {
        this.restrict = 'AC';
        this.replace = true;
        this.template = require('./templates/clock.tpl.html');
        this.scope = {};
    }
    link(scope, elem, attrs, $interval) {
        let end = new Date('05/05/2017 9:00 AM');

        let _second = 1000;
        let _minute = _second * 60;
        let _hour = _minute * 60;
        let _day = _hour * 24;

        scope.showRemaining = () => {
            let now = new Date();
            let distance = end - now;
            let days = Math.floor(distance / _day);
            let hours = Math.floor((distance % _day) / _hour);
            let minutes = Math.floor((distance % _hour) / _minute);
            let seconds = Math.floor((distance % _minute) / _second);

            scope.days = days;
            scope.hours = hours;
            scope.minutes = minutes;
            scope.seconds = seconds;
        }

        $interval(showRemaining, 1000;)
    }
}

// create factory function to handle DI
function factory() {
    "ngInject";

    return new Clock();
}

export default factory;

我正在搜索这个问题的原因并且无处不在我得到的信息是间隔函数必须作为普通函数传递而没有参数或任何其他插件。但我仍然有同样的错误,即:

TypeError: $interval is not a function

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:5)

您必须在构造函数中注入依赖项,而不是link函数:

constructor($interval) {
    // ..
    this.$interval = $interval;
}
link(scope, elem, attrs) {
    // ..
    this.$interval(showRemaining, 1000;)
}

答案 1 :(得分:0)

使用类构造指令对象的问题是指令函数具有非词法this(有关详细信息,请参阅this answer)。可以将$interval注入构造函数,但是在link函数中使用它是不可能的,而不会绑定它:

constructor($interval) {
  ...
  this.$interval = $interval;
  this.link = this.link.bind(this);
}

这表明存在设计问题。指令不适合课程。使用它们来构造指令对象并没有好处。这些类是不可重用的。他们没有建筑优势。

Angular 1.5+借用Angular 2中的想法(使迁移变得更容易是当前版本的任务之一)并以开发控制器为中心。这导致使用$onInit$postLink挂钩替换了预链接和后链接功能。

基于类的AngularJS开发的实用方法可能如下所示:

class ClockController {
  constructor($interval) {
    this.$interval = $interval;
  }

  $onInit() {
    this.$interval(() => this.showRemaining(), 1000);
  }

  showRemaining() { ... }
}

app.directive('clock', () => ({
  ...
  controller: ClockController
}));

此时将此指令转换为组件是有意义的,因为这是组件正在执行的操作。它们基本上是指令的包装器,强制以控制器为中心的方法。