2016-03-23 56 views
0

如果我的主幹模型具有關係(例如,由骨幹關係創建),那麼這些關係可能爲空,從而導致外鍵字段有時會變爲null如何防止Knockback.js爲空關係創建視圖模型?

如果我有幾個擊倒視圖模型,並且我已經指定了工廠,以便在跟隨關係時獲得具有模型所需功能的視圖模型,當它遇到屬性null時,它會繼續創建並創建視圖模型通過null作爲model,這可能會破壞大部分視圖模型的功能。

例子:

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 
     } 
    );