2016-03-23 13 views
0

バックボーンモデルにリレーションシップがある場合(たとえば、バックボーン - リレーショナルによって作成された場合)、これらのリレーションシップはNULL可能で、外部キーフィールドがnullになることがあります。Knockback.jsがヌル関係のビューモデルを作成するのを防ぐにはどうしたらいいですか?

私はいくつかのノックバック・ビュー・モデルを持っていて、リレーションをたどったときにモデルの目的の機能を持つビュー・モデルが得られるようにファクトリを指定しましたが、属性がnullになると、 nullmodelとして渡すビューモデルは、ほとんどのビューモデルの機能を破壊する可能性があります。

例:

var ChildViewModel = kb.ViewModel.extend({ 
    constructor: function (model, options) { 
     // this is the problem I'm trying to avoid - creating a view model with 
     // no model 
     if (!model) { 
      // just report the error somehow - the jsfiddle has the 
      // relevant HTML element 
      document.getElementById("error").innerHTML = "ChildModelView initialised without a model!"; 
     } 
     kb.ViewModel.prototype.constructor.apply(this, arguments); 
    } 
}); 

var ParentViewModel = kb.ViewModel.extend({ 
    constructor: function (model, options) { 
     // specify factories here, because this way you can easily deal with 
     // reverse relationships, or complicated relationship trees when you 
     // have a large number of different types of view model. 
     kb.ViewModel.prototype.constructor.call(
      this, 
      model, 
      { 
       factories: {relation1: ChildViewModel, 
          relation2: ChildViewModel}, 
       options: options 
      } 
     ); 
    } 
}); 

// if we assume that relation2 is a nullable relationship, backbone-relational, 
// for example, would give us a model that looks like this: 
var model = new Backbone.Model({ 
    id: 1, 
    relation1: new Backbone.Model({id: 2}), // this works fine 
    relation2: null // this causes a problem 
}); 

var view_model = new ParentViewModel(model); 

とフィドル:

https://jsfiddle.net/vbw44vac/1/

答えて

1

私はちょうど私が合理的な解決策になるかもしれないと思うものを発見しました。

ファクトリはViewModelの「クラス」である必要はありませんが、ファクトリ関数でもかまいません。だから、:

var nullable = function (view_model_class) { 
    var factory = function (object, options) { 
     if (object === null) return object; 

     return new view_model_class(object, options); 
    }; 
    return factory; 
}; 

そして、あなたの工場を定義している:

kb.ViewModel.prototype.constructor.call(
     this, 
     model, 
     { 
      factories: {relation1: nullable(ChildViewModel), 
         relation2: nullable(ChildViewModel)}, 
      options: options 
     } 
    );