2013-08-26 3 views
0

나는 새로운 객체를 생성 할 때 ID가 전달되었는지 확인하는 coffeescript 클래스를 작성하려고합니다. 그렇다면 일치하는 문서를 찾고 해당 개체를 채 웁니다. ID가 전달되지 않으면 새 ID를 생성하고 새 문서를 만듭니다. 내 mongodb에 연결하려면 mongojs을 사용하고 있습니다. 그러나 TestObject 클래스에서 새 객체를 만들면 컬렉션 이름이 문자열이어야한다는 오류가 발생합니다. @collection을 해당 클래스의 문자열로 설정하여 console.log에 @collection 속성과 undefined를 설정합니다. 무슨 일이 벌어지고 어떻게이 일을 할 수 있니?Coffeescript 클래스는 mongo 문서를 찾거나 만듭니다.

class MongoObject 
    @collection 
    constructor: (id) -> 
     @_id = if typeof id is 'undefined' then require('node-uuid').v4() else id 
     @db = require('mongojs') config.mongo_server, [@collection] 

     @db[@collection].findOne 
      _id: @_id, 
      (error, story) -> 
       # Matching document found. Import data from document 
       if not error and story 
        for field, value of story 
         @[field] = value if field is not '_id' 

       # Matching document not found. Creating new one 
       if not error and not story 
        @db[@collection].save 
         id: @id 

       # Error occured 
       if error and not story 
        console.error error 

       return 

class TestObject extends MongoObject 
    @collection = 'TestObjects' 
    constructor: (id) -> 
     super('TestObject') 

편집

생성자와 @collection과의 문제가 MongoObject에 정의되지 않은되고 있음은 분명 내 코드를 다시 읽기. 이 작업을 수행하는 더 좋은 방법이 있습니까? setupDB 메쏘드를 생성하고 수퍼 콜 후에 MongoObject를 확장하는 각 클래스의 생성자에서 그것을 호출 할 수는 있지만, 내가 원하는 것은 아닙니다. 2

편집 난 내 코드를 수정. 그러나 지금 나는 constructor이 정의되지 않았다는 오류가 발생합니다. 컴파일 된 자바 스크립트를 보았을 때 MongoObject 코드 상단에 constructor;을 가리켰습니다. 이상하게도 coffeescript는 보통 var constructor;을 넣지 않았습니다. 난 그냥 참조

커피 스크립트

class MongoObject 
    collection: undefined 
    constructor: (id) -> 
     @_id = if typeof id is 'undefined' then require('node-uuid').v4() else id 
     @db = require('mongojs') config.mongo_server, [@collection] 

     @db[@collection].findOne 
      _id: @_id, 
      (error, story) -> 
       # Matching document found. Import data from document 
       if not error and story 
        for field, value of story 
         @[field] = value if field is not '_id' 

       # Matching document not found. Creating new one 
       if not error and not story 
        @db[@collection].save 
         id: @id 

       # Error occured 
       if error and not story 
        console.error error 

       return 

class TestObject extends MongoObject 
    collection = 'TestObjects' 
    constructor: (id) -> 
     super('TestObject') 

자바 스크립트

MongoObject = (function() { 
    MongoObject.prototype.collection = void 0; 

    function MongoObject(id) { 
    this._id = typeof id === 'undefined' ? require('node-uuid').v4() : id; 
    this.db = require('mongojs')(config.mongo_server, [this.collection]); 
    this.db[this.collection].findOne({ 
     _id: this._id 
    }, function(error, story) { 
     var field, value; 
     if (!error && story) { 
     for (field in story) { 
      value = story[field]; 
      if (field === !'_id') { 
      this[field] = value; 
      } 
     } 
     } 
     if (!error && !story) { 
     this.db[this.collection].save({ 
      id: this.id 
     }); 
     } 
     if (error && !story) { 
     console.error(error); 
     } 
    }); 
    } 

    return MongoObject; 

})(); 

TestObject = (function(_super) { 
    var collection; 

    __extends(TestObject, _super); 

    collection = 'TestObjects'; 

    function TestObject(id) { 
    TestObject.__super__.constructor.call(this, 'TestObject'); 
    } 

    return TestObject; 

})(MongoObject); 

3

내 의견에 따라 내 코드를 업데이트 편집에 대한 번역 된 자바 스크립트를 게시했습니다. 그 @constructor.collection

@db[@constructor.collection].save 
    id: @id 

에 정의되지 말 것을 나는 그것의 콜백 함수의은을 저장하기 때문에 가정합니다. 한 단계 앞으로, 두 걸음 뒤로.

개정 코드

class MongoObject 
    @collection 
    constructor: (id) -> 
     @_id = if typeof id is 'undefined' then require('node-uuid').v4() else id 
     @db = require('mongojs') config.mongo_server, [@constructor.collection] 

     @db[@constructor.collection].findOne 
      _id: @_id, 
      (error, story) -> 
       # Matching document found. Import data from document 
       if not error and story 
        for field, value of story 
         @[field] = value if field is not '_id' 

       # Matching document not found. Creating new one 
       if not error and not story 
        @db[@constructor.collection].save 
         id: @id 

       # Error occured 
       if error and not story 
        console.error error 

       return 

class TestObject extends MongoObject 
    @collection: 'TestObjects' 
    constructor: (id) -> 
     super('TestObject') 
+0

로 결국 해결책은? –

+0

상위 클래스의 생성자를 실행하기 위해 super가 호출되고 있습니다. super는 파이썬에서 같은 방식으로 사용됩니다. http://arcturo.github.io/library/coffeescript/03_classes.html "실제로는 Ruby 또는 Python에서 super를 호출하여 재정의 된 상속 된 함수를 호출하는 것과 똑같은 효과가 있습니다." 먼저 부모 생성자 로직을 호출하고 싶습니다. – Kylee

+0

궁극적으로 db 연결 코드가있는 기본 클래스와 컬렉션 이름을 정의하는 각 확장 클래스가 필요하므로 @db는 각 클래스 정의마다 올바른 컬렉션을 가리킬 것입니다. 그래서 나는 코드를 반복해서 반복하지 않는다. – Kylee

답변

1

난 당신이 클래스 수준에서 @의 의미에 대한 혼란 것 같아요.

var B = (function() { 
    function B() {} 
    B.p = 'b'; 
    return B; 
})(); 

그래서 당신이 p 직접 C 클래스/함수에 연결되어 클래스 속성이라고 볼 수

class B 
    @p: 'b' 

이 자바 스크립트와 동일합니다 : 단순화 된 예는이 커피 스크립트를 도움이 될 것입니다 . 그러나 constructor과 같은 메서드를 사용하는 경우 을 클래스 속성으로 정의 했으므로 @collectionundefined이되므로 인스턴스를 참조하면 @이 인스턴스를 참조합니다.

class MongoObject 
    collection: undefined 
    constructor: (id) -> 
     # @collection is what you expect it to be in here 

class TextObject extends MongoObject 
    collection: 'TextObject' 

데모 : : 또는 http://jsfiddle.net/ambiguous/TzK5E/

, 당신은 클래스 속성으로 collection을 유지하고 @constructor를 통해 참조 할 수 있습니다 :

class MongoObject 
    @collection: undefined 
    constructor: (id) -> 
     # @constructor.collection is what you expect it to be in here 

class TextObject extends MongoObject 
    @collection: 'TextObject' 
을 당신은 아마 인스턴스 속성으로 collection 원하는

데모 : http://jsfiddle.net/ambiguous/wLjz3/

+0

확실히 작동합니다. 클래스와 그 클래스에서 생성 된 모든 객체에 대한 설정 이후 클래스 변수가 될 것이라고 생각했습니다. 인스턴스 변수 나는 클래스에서 생성 된 객체에 대한 변수를 생각하며 서로 고유하다. 새로운 것을 배우기에 좋은. – Kylee

+0

이것은 클래스 변수이지만 인스턴스 메서드 내에서 "클래스"를'@ constructor '로 참조해야합니다. –

0

나는 당신이 collection 이름을 참조하는 약간 다른 구문을 사용하는 것이 좋습니다 생각 :

class MongoObject 
    @collection 
    constructor: (id) -> 
     alert @constructor.collection 


class TestObject extends MongoObject 
    @collection = 'TestObjects' 
    constructor: (id) -> 
     super('TestObject') 

t = new TestObject 

경고

의 핵심은 @constructor.collection의 사용이다.

0

이것은 당신이`모음 = 'TestObjects'`이해야 할 이유는`슈퍼 일을 기대`생성자 ('TestObjects ')를 내가

class MongoObject 
    @collection 
    constructor: (id) -> 
     @_id = if typeof id is 'undefined' then require('node-uuid').v4() else id 
     @db = require('mongojs') config.mongo_server, [@constructor.collection] 

     @db[@constructor.collection].findOne 
      _id: @_id, 
      (error, doc) => 
       # Matching document found. Import data from document 
       if not error and doc 
        console.log 'Document found. Updating.' 
        for field, value of doc 
         @[field] = value if field is not '_id' 

       # Matching document not found. Creating new one 
       if not error and not doc 
        console.log 'No document found. Creating.' 
        @db[@constructor.collection].save 
         _id: @_id 

       # Error occured 
       if error and not doc 
        console.error error 

       return 

class TestObject extends MongoObject 
    @collection: 'TestObjects'