2014-10-03 86 views
0

在下面的一些API中,它需要我想在构造函数中动态分配的凭据。然后我想在整个班级中使用一些API。即在下面的例子中someMethodUsingSomeAPI是一个帮助方法,我想从B的一个实例中的其他方法中调用。这对Coffee-/JavaScript来说可能吗? (我可以让它开始工作的唯一方法是,如果我把someMethodUsingSomeAPI在构造函数中。)从构造函数实例化的全范围对象

SomeAPI = Npm.require 'someAPI' 

class B extends A 
    constructor: (options = {}) -> 
    unless @ instanceof B 
     return new B(options) 

    @config = JSON.parse(Assets.getText('config/' + options.username + '.json')) 

    @someAPI = new SomeAPI 
     consumer_key: @config.credentials.consumer.key 
     consumer_secret: @config.credentials.consumer.secret 
     access_token: @config.credentials.access.token 
     access_token_secret: @config.credentials.access.secret 

    someMethodUsingSomeAPI = Async.wrap((id, callback) -> 
    return @someAPI.get 'whatever/show', { 'id': id }, callback 
) 

    console.log someMethodUsingSomeAPI '123' # Error: Cannot call method 'get' of undefined 

已更新,建议从saimeunt

... 

someMethodUsingSomeAPI = (id) -> 
    wrappedGet = Async.wrap(@someAPI, 'get') 
    wrappedGet 'whatever/show', { id: id } 

console.log someMethodUsingSomeAPI '123' # ReferenceError: someMethodUsingSomeAPI is not defined 

&

b = B('username') 
b.someMethodUsingSomeAPI '123' # Works! 

更改someMethodUsingSomeAPI:someMethodUsingSomeAPI =

console.log someMethodUsingSomeAPI '123' # Error: unsupported argument list 

&

b = B('username') 
b.someMethodUsingSomeAPI '123' # TypeError: Object #<B> has no method 'someMethodUsingSomeAPI' 

(这与流星0.9.3.1)

UPDATE IN试图澄清

Here's a simplified version of the above, without any of the API stuff.

someMethod = workssomeMethod: doesn't work

我很高兴classInstance.someMethod在使用时有效,但真的很想让它在实际情况下工作。

+0

为什么让'someAPI'静态变量类之外,而不是实例*物业,*? – Bergi 2014-10-03 00:45:27

+0

请注意,'JSON.parse'确实需要一个JSON字符串,而不是文件路径。 – Bergi 2014-10-03 00:45:52

+0

对,对不起。为简洁起见,删除了一些内容。加回来。 – jiku 2014-10-03 01:02:05

回答

0

当然,您可以将someAPI附加到您的类对象上。在咖啡标@用于代替this(因为它会在Javscript中)。

SomeAPI = require 'someAPI' 

class A extends B 
    constructor: (options = {}) -> 
    unless @ instanceof A 
     return new A(options) 

    @config = JSON.parse('config/' + options.username + '.json') 

    @someAPI = new SomeAPI 
     consumer_key: @config.credentials.consumer.key 
     consumer_secret: @config.credentials.consumer.secret 
     access_token: @config.credentials.access.token 
     access_token_secret: @config.credentials.access.secret 

    someMethodUsingSomeAPI: (id, callback) -> 
    return @someAPI.get 'whatever/show', { 'id': id }, callback 

你可以看看this SO question这也解释了JavaScript的this,其范围。一旦你明白了,看看coffeescript's classes是如何工作的,你应该对@的使用有一定的了解。

+0

谢谢。我想我尝试了这一点,在尝试在构造函数之外声明一些API之前,尝试了这些。更新原始文章以反映我正在做什么,但是我仍然得到相同的错误,即'Can not call method'get'of undefined'。 – jiku 2014-10-03 01:07:06

0

我想这是你想要什么:

someMethodUsingSomeAPI:function(id){ 
    var wrappedGet=Async.wrap(@someAPI,"get"); 
    return wrappedGet("whatever/show",{ 
    id:id 
    }); 
} 
+0

这对于b.someMethodUsingSomeAPI非常有效,但除非我搞砸了CS,否则它在实例内不起作用。结果更新了上面的例子。 – jiku 2014-10-03 02:32:58

+0

在定义对象文字的新属性时,请删除'='而不是':',因为如果你不这样做,它绝对没有SENSE,我不知道地球上的CS怎么没有警告你。如果没有“新”的B这些instanciations?您是否在其他方法中使用正确的语法调用了一些Method,使用了SomeAPI,即'@ someMethodUsingSomeAPI'? – saimeunt 2014-10-03 02:54:03

+0

好的。我不知道为什么,但使用=我实际上有'console.log someMethodUsingSomeAPI'123''工作,如果我把两者都在构造函数。 B wit(out)new似乎没有什么区别。只要返回一个新的,除非已经在构造函数中声明了B的一个实例。如果我做了'console.log @someMethodUsingSomeAPI'123'',我得到了'TypeError:Object#没有方法'someMethodUsingSomeAPI'' – jiku 2014-10-03 03:05:11

0

基于你在这里提供的简单的例子是应该符合您要求的版本:

class SomeClass 
    # Store the last created instance at the class level 
    lastInstance: null 

    constructor: (options = {}) -> 
    @someLastName = options.someLastName 
    # In constructor, the created instance is now the lastInstance 
    SomeClass.lastInstance = this 

# The helper method is not created in the class scope 
someMethod = (someFirstName) -> 
    "Hello " + someFirstName + " " + SomeClass.lastInstance.someLastName 

someClass = new SomeClass({ someLastName: 'Borgnine' }) 

alert someMethod 'Ernest' 

而且here's a link to try it in a browser

基本上,正如你所期望的帮助方法访问类的一个实例,你需要提供一个引用帮助者可以在某个时候引用该实例。在这里,我使用一个类变量来存储上次创建的实例,以及最后一次调用时的辅助访问。这意味着,创造了许多实例时,将如下进行:

someClass = new SomeClass({ someLastName: 'Borgnine' }) 

alert someMethod 'Ernest' # Hello Ernest Borgnine 

someClass = new SomeClass({ someLastName: 'Doe' }) 

alert someMethod 'Boris' # Hello Boris Doe 
相关问题