将变量从@Injectable传递给Component

时间:2017-02-09 16:30:45

标签: javascript jquery angular typescript twilio

在此段落下方的代码块中,您可以看到Twilio.Device.incoming,我将this.connection设置为conn

@Injectable()
    export class BaMsgCenterService {
        public getData;
        public incomingCall = false;
        public connection;

        constructor(private http: Http) {
            this.initTwilio();

            Twilio.Device.ready(function (device) {
                self.incomingCall = true;
                $(".card-title").text("Ready to receive incoming calls!");
            });

            Twilio.Device.incoming(function (conn) {
               console.log(conn.status);
               this.incomingCall = true;
               this.connection = conn;
            });
            //other functions
         }
    }
}

比我有一个组件类:

import {Component} from '@angular/core';
import { Http } from '@angular/http';

import {BaMsgCenterService} from './baMsgCenter.service';

@Component({
   selector: 'ba-msg-center',
   providers: [BaMsgCenterService],
   styleUrls: ['./baMsgCenter.scss'],
   templateUrl: './baMsgCenter.html'
})
export class BaMsgCenter {
   public connection;

   constructor(private _baMsgCenterService:BaMsgCenterService) {
      this.connection = this._baMsgCenterService.connection;
   }
   pickup() {
       this.connection.accept();
  }

}

在html代码中,我有(click)="pickup()"

然而,当我点击它时,它表示conn不存在。

inline template:63:10 caused by: Cannot read property 'accept' of undefined

我想使拾取功能起作用,它必须能够在拾取功能中使用conn(或this.connection)。我认为Twilio.Device稍后会执行(它是一个API)......

4 个答案:

答案 0 :(得分:2)

Twilio开发者传道者在这里。

当您在构造函数中设置this.connection = this_baMsgCenterService.connection时,您并未将这两个变量绑定在一起,而只是将this.connection指向同一位置this._baMsgCenterService.connection is pointing, which is未定义at the time. When。 _baMsgCenterService.connection is updated it doesn't change this.connection`。

以下是一个更简单的例子:

var a, b;
a = b = "foo";
b = "bar";
console.log(a); // "foo";
console.log(b); // "bar";

您需要继续参考消息中心服务的连接。您可以使用实例方法而不是属性来执行此操作。

类似的东西:

export class BaMsgCenter {
   constructor(private _baMsgCenterService:BaMsgCenterService) {}

   pickup() {
     this.connection().accept();
   }

   connection() {
     this._baMsgCenterService.connection;
   }
}

让我知道这是否有帮助。

修改

我仍然认为我回答了问题的一半,但关于事件中this的背景的答案也是正确的。

答案 1 :(得分:1)

使用

(conn) => {

而不是

function (conn) {

还会将function的所有其他出现更改为箭头功能样式,否则this.将不会按预期指向服务或同类。

答案 2 :(得分:1)

你错了this。使用function语法时,this动态绑定到调用的目标,也就是说它被绑定到用作方法时调用该函数的对象。你有两个选择。

别名this使用局部变量在闭包中使用:

var that = this;

takesAFunction(function (value) {
  that.prop = value;
});

如果您的目标是现代版本的NodeJS或现代浏览器,或者您有权访问转换器;如TypeScript,Babel或Traceur;只需使用ES2015箭头功能:

takesAFunction(value => {
  this.prop = value;
});

箭头函数this内部是静态范围的,也称为词法范围,与语言中的每个其他标识符一样。

第二种方法可以提供更清晰的代码,在可行的情况下应该首选。

答案 3 :(得分:0)

一个错误是基本服务懒惰地设置connection。在构造函数/初始化中它尚未存在,因此初始化为undefined。我猜你在这里开始一个异步操作来获取它,并在回调中将它存储在服务中:

Twilio.Device.incoming(function (conn) {
    console.log(conn.status);
    this.incomingCall = true;
    this.connection = conn;
});

您现在可能需要做的是在BaMsgCenter中等待,直到连接可用。例如。仅在连接存在时创建BasMsgCenter。或者通过在基本服务中将其作为Promise或添加另一个表示可用性的承诺,从MsgCenter订阅到此并仅在分配后使用该连接。如果您可以保证仅在先前分配连接时才调用pickup,则不需要。

另一个错误就像GünterZöchbauer也指出this并没有真正指向你的BaMsgCenterService类的实例,可以通过使用箭头函数来修复它。