2011-09-27 20 views
12

プライベート変数とパブリック変数をどこに置くかというバックボーンビューです。バックボーンビューへのプライベート変数とパブリック変数

今、私はこのようなものがあります:

myView = Backbone.View.extend({ 

    initialize: function(options){ 
    this.myPublic = "I'm public"; 
    } 

}); 

を私はinitializeメソッドの前にvar myPrivateを追加しようとしたが、それはエラーを投げました。ビュー内でのみ使用されるプライベート変数はどこに行きますか?

+0

なぜあなたは説明してもらえこれをやろうとしている?実際にはまっすぐな解決策はありません。 – Gazler

+0

私はどのようにビューにプライベートプロパティを追加することができますからappartを説明することはあまりありません。 var myPrivate = "private property"の例ですが、これはthis.myPublicのようにビュー全体で使用できるはずです。ただし、this.myPublicはビューインスタンスからアクセスできます。 myPrivateはビューメソッド自体からのみアクセスできます – Chapsterj

+1

この回答を見る http:// stackoverflow。com/questions/8924961/private-like-properties-in-models-or-views-of-backbone-js –

答えて

11

自己呼び出す匿名関数でそれをすべてをラップ:

(function() { 
    var myPrivate = 1; 

    myView = Backbone.View.extend({ 
     initialize: function(options){ 
      this.myPublic = "I'm public"; 
      myPrivate++; 
     }, 
     render: function() { 
      alert(myPrivate); 
     } 
    }); 

})(); 

編集を:としては、上記の例では、インスタンス間で共有されるプライベート変数を作成し、以下のkaustubh's commentで指摘。 という変数を保護することができます。つまり、ビューの他のインスタンスが読み取ることができるインスタンスレベルの変数です。各インスタンスに一意のパブリックIDを与え、インスタンス変数を「プライベート静的」変数に格納します。

(function() { 
    var data = []; 

    myView = Backbone.View.extend({ 
     initialize: function(options){ 
      this.myPublic = "I'm public"; 
      this.Id = data.length; 
      data.push({}); 
      data[this.Id].myProtected = "abc"; 
     }, 
     render: function() { 
      alert(data[this.Id].myProtected) 
     } 
    }); 
})(); 

または、公共のIDを使用せずにそれを行うことができますが、それはもう少し複雑になり:次にインスタンスIDによって変数にアクセス

(function() { 
    var data = (function() { 
     var dataValues = []; 
     return function (instance) { 
      for (var i = 0; i < dataValues.length; i++) { 
       if (dataValues[i].instance === instance) { 
        return dataValues[i].data; 
       } 
      } 
      var dataObject = { instance: instance, data: {} }; 
      dataValues.push(dataObject); 
      return dataObject.data; 
     }; 
    })(); 

    myView = Backbone.View.extend({ 
     initialize: function(options){ 
      this.myPublic = "I'm public"; 
      data(this).myProtected = "abc"; 
     }, 
     render: function() { 
      alert(data(this).myProtected) 
     } 
    }); 
})(); 

私が思い付くのに苦労しています真にプライベート変数を格納する方法。インスピレーションが襲ったら、私は返信します。

+0

最後に角括弧を忘れて、実際に自己呼び出しするようにしてください。 – Gazler

+0

@Gazler - 良いキャッチ、ありがとう! – gilly3

+0

ありがとうございましたGazler、このビューのインスタンスをどのように作成しますか?または、ビュー – Chapsterj

19

他のすべてのメソッドについては、initializeメソッドをクロージャとして使用することをお勧めします。 「この」使用

 

myView = Backbone.View.extend({ 

    initialize: function(options){ 
    var myPrivate = "I'm private"; 

    this.myPublic = "I'm public"; 

    this.getPrivate = function() { 
     return myPrivate; 
    }; 

    this.setPrivate = function (value) { 
     if (typeof(value) === 'string') { 
      myPrivate = value; 
      return true; 
     } else { 
      return false; 
     } 
    }; 
    } 
}); 
+0

プライベート変数を使用するinitialize内部のメソッドを追加しますか?オブジェクトを作成するたびに初期化を遅くしますか? –

+1

@StalinGinoはい。誰かが感じる減速であるかどうかはわかりませんが、それは確かに記憶の中でより多くのスペースを占めるでしょう。 – pilau

-2

:私は、これは我々がC++やJavaなどの古典の継承言語で何を得ると、より一貫性のある、あなたの行動を与えると思いますか?

 

    initialize:function() { 
     this.viewpointers = {} 
    }, 
    render:function() { 
     var self = this 
     _.each(this.viewpointers, function(item){ 
      self.$el.find(".assigned-items").append(item.render().el) 
     }); 
    } 

です。その後、これらは少なくとも保護されています。それは技術的にプライベート変数を使用して作成/されていないが、同じ閉鎖の他のインスタンスがそれにアクセスする必要がありますので

 

    this.viewpointers[model.id] = new view({model:model}) 

0

gilly3のソリューションは、最良の答えかもしれ(おそらくあなたの他のメンバーについてなど心配はありません開発チームはその特権を悪用しますが、起こる可能性があります)。

あなたはgilly3のアプローチを使用せずにプライベート変数を使用したい場合はダグラス・クロックフォードは、ここでプライベート変数を作成する方法を説明しているように、近くPrivmanの答えが唯一の真のソリューションであることが表示されます。http://javascript.crockford.com/private.html

これは、以来、追加のJavaScriptの処理時間が追加されますプロトタイプの継承を利用することはできず、そのたびに関数を再作成するためにリソースを使用します。

ただし、毎回作成するクロージャーが非常に小さい場合や、新しいインスタンスが作成される回数が最小限に抑えられている場合は、これは非常に目立つ問題ではありません。両方の世界を最高にしようと努力するために、プライベート変数(via delegation pattern)を使用するメソッドの大部分を毎回再作成されない静的関数に委譲することができます。これにより、下に表示されるpublicMethodThatUsesPrivateVariableメソッドが小さくなります。つまり、毎回再作成するのにかかる時間が短縮されます。

var _privateStaticMethod = function(privateVariableValue, methodParameter) { 
     var result; 

     // Execute the lengthy javascript logic here ... 

     result = Math.ceil(privateVariableValue/108); 
     result += 4815162342; 
     return result; 
    }; 

    Backbone.View.extend({ 
     initialize: function() { 
      var _privateVariable = 303; 

      this.publicMethodThatUsesPrivateVariable = function(methodParameter) { 
       // Only place as little logic as you can here outside of the private static method being used below 
       _privateVariable += 1; 

       return _privateStaticMethod(_privateVariable, methodParameter); 
      }; 
     }, 

     // ... 
    }); 

_privateStaticMethodグローバル変数/関数ではないように上記のコードは、同様の機能のいくつかの種類に包まれるべきであることに留意されたいです。

1

オブジェクトを直接extend関数に挿入する代わりに、closureを作成してそのclosureからオブジェクトをextend関数に戻す方法はありますか?

var myView = Backbone.View.extend(function() { 

    var _myPrivateOne = 0; 

    function _myPrivateStrangeSquareFunction(a) { 
    return a * a + 1; 
    } 

    return { 
    initialize: function (options) { 
     _myPrivateOne = options.privateOne; 
     this.myPublicOne = options.publicOne; 
    }, 
    setPrivateOne: function (value) { 
     _myPrivateOne = value; 
     return _myPrivateOne; 
    }, 
    getPrivateOne: function() { 
     return _myPrivateOne; 
    }, 
    getPrivateOneStrangelySquared: function() { 
     return _myPrivateStrangeSquareFunction(_myPrivateOne); 
    } 
    }; 

}()); 

私はバックボーンのインストールを今すぐ利用できないため、これを試していません。

+0

私は、これらのプライベート変数がこのビューの複数のインスタンスによって共有されることに気付きました。この修正は次のようになります。 _privates = {}; _privates [this.cid] = {}; //特定のオブジェクトに対するプライベートなものを格納するためのオブジェクト(cidによる)。 – jgroenen

0

「スーパー」メソッドをオーバーライドして問題に遭遇するまで、私は近くのPrivmanの答えを好みました。 initialize()は、何らかの方法でBackboneオブジェクトを構築するまで呼び出されていないため、必要なときにオーバーライドが発生していない可能性があります(initialize()が呼び出される前に必要です)。

特に、これはparse()の問題である可能性があります。 (未ビューの問題、間違いなくコレクションとモデルのため。)この設定を考える:

MyModel = Backbone.Model.extend({ 
    initialize: function (options) { 
     this.parse = function (response, xhr) { 
      // parsing logic 
     }; 

     // public & private vars/methods here 
     // and also initialize code 
    } 
}); 

MySubModel = MyModel.extend({ 
    initialize: function (options) { 
     this.parse = function (response, xhr) { 
      // override MyModel with my own parsing logic 
     } 

     // public & private vars/methods here 
     // and initialize code here 
    } 
}); 

MySubModel.parse()が呼び出されることはありません。

代わりに、initialize()の代わりにIIFEを使用すると、この問題が解決され、すでに指定された目的(initialize())を持つ関数を他のものを定義するクロージャクラスの

var MyModel = {}; 
(function() { 
    this.initialize = function (attributes, options) { 
     // initialize me 
    } 

    this.parse = function (response, xhr) { 
     // override at will 
    } 

    // other public & private vars/methods here 
}).call(MyModel); 

Backbone.Model.extend(MyModel); 

残念ながら、これはgilly3と近くPrivmanの答えの両方がそうであるように、クラスのすべてのインスタンス間で共有されている「プライベート」の変数と同じ問題を抱えています。プライベート変数を可能にするために厄介ではない方法を聞くのが大好きですが、多分私はそれをあきらめて、Java/AS3/C++ではなくJavaScriptを書いていることを認識する必要があります。

0

あなたがこの試すことができます:

var Thing = Backbone.Model.extend(
    { 
     constructor : function() 
     { 
      var _value = "Private data!"; 

      this.getValue = function() 
      { 
       console.log(_value); 
      }; 
      this.setValue = function (value) 
      { 
       _value = value; 
      }; 
     } 
    }); 
0

を「プライベート」の変数を追加する標準のバックボーンの方法は、彼らの前にアンダースコア「_」との属性として宣言することです。彼らは本当に私的ではありませんが、開発者は公に使われることを意図していないことを認識します。

実際、これはバックボーンが独自のプライベート変数を格納する方法です。バックボーンとBroserify.jsを使用してのコンテキスト(および中規模プロジェクト上記本当にすべて)で

0

私はプライベートVARSと機能を持ってするには、次の方法を見つけた:

myView.js

'use strict'; 

var config  = require('../config.js'), 

    private_var = 'private variable', 
    my_private_fn = function() { 
     ... 
    }; 


module.exports = Backbone.Model.extend({ 
    initialize: function() { 
     this.my_public = 'public variable'); 

     console.log('This is my' + this.my_public); 
     console.log('This is my' + my_private); 
    }, 
}); 
関連する問題