1

私はアプリケーションを構築していて、Backbone.jsを使用しています。私はBackboneに慣れていないので、そこでドキュメントを読み、複数のアプリを調べてテストし、Backboneのパターンを読みました。

今、私はバックボーンプリンシパル全体を理解し始めていますが、何かに少し問題があります。グローバルオブジェクト(例:)がありApp、その中にビュー、モデル、...を配置します(例:) App.Views.ListView。ここで問題となるのは、これらのオブジェクトを拡張する必要があることです。これは、オブジェクト内にデフォルト値が存在する可能性があるためです。

だから私が始めたとき、私はこのようなものを持っていました

App.Views.ListView = Backbone.View.extend({});

でも今はこんなもの欲しい

_.extend(App.Views.ListView, Backbone.View.extend({});

これは私が望むようには機能しません。App.Views.ListViewが存在します(これは、ファイルオブジェクト構造を確認し、拡張が何かを行う構成ファイルで定義されています)。問題は、ビューのインスタンスを作成できないことです(例new App.Views.ListView();

例:

私の設定で作成されたオブジェクト

App:{
 Views:{
  ListView:{
   myVar: "hello"
   DeeperList: {
   }
  }
 }
}

見てみると、オブジェクトApp.Views.ListViewには、値helloの変数とオブジェクトDeeperListが含まれていることがわかります。しかし、このオブジェクト内に、myVarとDeeperListを上書きせずにビューを追加したいと思います。使用App.Views.ListView = Backbone.View.extend({});すると上書きされますが、これを回避する方法があります。拡張を使用するように...

この問題を抱えていた人は、それを解決する方法を知っていますか?

本当にありがとう!

4

3 に答える 3

1

したがって、これは必要なオブジェクトです。

App = {
    Views: {
        ListView: {
            myVar: "hello"
            DeeperList: {}
        }
    }
}

最初のパラメータをtrueに設定してjQuery拡張を実行するだけで、この名前空間を別のオブジェクト/名前空間に深く拡張/マージします

(function(App, ListView, undefined){
    $.extend(true, ListView, {
        'DeeperList': Backbone.View.extend({

        })
    });
})(window.App, App.Views.ListView);

javascriptの名前空間の詳細については、次の興味深いブログ投稿をご覧ください:http: //addyosmani.com/blog/essential-js-namespacing/

jQueryを使用しない場合は、ブログ投稿に記載されている拡張関数を使用することもできます。

function extend(destination, source) {
    var toString = Object.prototype.toString,
        objTest = toString.call({});
    for (var property in source) {
        if (source[property] && objTest == toString.call(source[property])) {
            destination[property] = destination[property] || {};
            extend(destination[property], source[property]);
        } else {
            destination[property] = source[property];
        }
    }
    return destination;
};
于 2012-06-06T15:11:50.890 に答える
0

私があなたを正しく理解していれば、それApp.Views.ListViewは一種のミックスインです。したがって、次のようなことができます。

var App.Views.ExtendedListView = Backbone.View.extend(_.extend(App.Views.ListView, {
    newMethod: function () {
        // ...
    }
}));

var extListView = new App.Views.ExtendedListView();

少し醜いように見えますが、機能します。あなたがあなたを示すことができればApp.Views.ListView、多分私たちはより美しい決定を見つけることができます。

于 2012-06-05T12:23:54.683 に答える
0

バックボーンextendはアンダースコアと同じではありませんextend。アンダースコアは、オブジェクトプロパティを(浅く)コピーするためextendのループにすぎません。for

_.extend = function(obj) {
  each(slice.call(arguments, 1), function(source) {
    for (var prop in source) {
      obj[prop] = source[prop];
    }
  });
  return obj;
};

バックボーンextendはその内部inherits関数のラッパーです:

var extend = function(protoProps, classProps) {
  var child = inherits(this, protoProps, classProps);
  child.extend = this.extend;
  return child;
};

//...

// Helper function to correctly set up the prototype chain, for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var inherits = function(parent, protoProps, staticProps) {
  var child;
  // [Bunch of code for properly setting up the prototype chain and elided]...
  return child;
};

return child両方の呼び出しに注意してくださいextendinherits両方とも新しいものを作成して返します。引数は変更しません。

_.extendビューの「クラス」を既存のオブジェクトに混在させるために使用する場合の問題:

_.extend(App.Views.ListView, Backbone.View.extend({});

つまり_.extend、プロトタイプでは何_.extendもしません。また、オブジェクトを魔法のように関数に変換しないため、何が得られるかを呼び出すことはできませnew_.extend。プロパティをビューの「クラス」に混在させることはできますが、プロパティをに混在させてprototype、ビューを最終的な宛先に割り当てて、次の関数を取得する必要がありますApp.Views.V

var V = Backbone.View.extend({ ... }); // Create the view.
_.extend(V.prototype, App.Views.V);    // Mix App.Views.V into its prototype.
App.Views.V = V;                       // Replace App.Views.V with our view function.

デモ: http: //jsfiddle.net/ambiguous/5KSbw/

そのすべてのchicaneryは、このコードを拡張および維持しなければならない貧しい魂を混乱させるので、私はそれに反対することをお勧めします。デフォルトを保持するために別のオブジェクトを使用する方がよいでしょう。

var DEFAULTS = {
    Views: { ... }
};

次に、これらのデフォルトを明示的に参照します。

App.Views.ListView = Backbone.View.extend({
    myVar: DEFAULTS.Views.ListView.myVar,
    //...
});

ただし、問題が発生します。参照をコピーしたばかりの場合DeeperListは、バージョンが変更されないように、コンテンツを明示的にコピーする必要があります。DEFAULTS

App.Views.ListView = Backbone.View.extend({
    DeeperList: _.extend({}, DEFAULTS.Views.ListView.myVar),
    //...
});

また、オブジェクトまたは配列が含まれている場合は、ディープコピーを取得するための最初の引数としてjQueryをDeeperList使用する必要があります。$.extendtrue

App.Views.ListView = Backbone.View.extend({
    DeeperList: $.extend(true, {}, DEFAULTS.Views.ListView.myVar),
    //...
});
于 2012-06-05T16:06:30.253 に答える