2015-08-06 4 views
1

У меня есть config.json, что я собираюсь загрузить в мое приложение в качестве основы модели, как:Инициализировать магистральная Модели на основе другого Backbone модели

var Config = Backbone.Model.extend({ 
    defaults: { 
     base: '' 
    }, 
    url: 'config.json' 
}); 

Другие модели должны зависеть от некоторых данных, содержащихся в Config, как:

var ModelA = Backbone.Collection.extend({ 
    initialize: function(){ 
     //this.url should be set to Config.base + '/someEndpoint'; 
    } 
}); 

В приведенном выше примере, ModelA «ы url свойство зависит от Config» ы стоимости base имущества.

Как я могу правильно настроить его в приложении Backbone?

+0

Один из способов переопределить [ 'Backbone.sync'] (http://backbonejs.org/#Sync) – hindmost

+0

@hindmost Простой образец кода будет оценен по достоинству. Я новичок в Backbone. Благодарю. – lbrahim

+1

Здесь не может быть простых образцов. Однако я предлагаю посмотреть [мое приложение JS] (https://github.com/hindmost/jslogflush-manager), [где] (https://github.com/hindmost/jslogflush-manager/blob/master/manager .js # L5) Backbone.sync overriding используется для задачи simliar как вашего. – hindmost

ответ

2

Как я понимаю, ваши основные вопросы:

  • Как мы получим экземпляр модели конфигурации?
  • Как мы будем использовать конфигурационную модель для установки зависимой модели url?
  • Как мы можем убедиться, что мы не используем функцию url на зависимой модели слишком рано?

Есть много способов справиться с этим, но я собираюсь предложить некоторые особенности, чтобы я мог просто предоставить руководство и код и «сделать это», так сказать.

Я думаю, что лучший способ справиться с первой проблемой - сделать эту конфигурационную модель синглом. Я собираюсь предоставить код из backbone-singleton GitHub страницы ниже, но я не хочу, чтобы ответ на вытянутый по вертикали, пока я не сделал с объяснением, так что читайте дальше ...

var MakeBackboneSingleton = function (BackboneClass, options) { ... } 

Далее, мы Сделайте одно из одной точки: AppConfiguration, а также недвижимость для аренды jQuery. Результат fetch обеспечит always(callback), done(callback) и т.д.

var AppConfiguration = MakeBackboneSingleton(Backbone.Model.extend({ 
    defaults: { 
     base: null 
    }, 
    initialize: function() { 
     this.deferred = this.fetch(); 
    }, 
    url: function() { 
     return 'config.json' 
    } 
})); 

Теперь время, чтобы определить зависимую модель DependentModel, которая выглядит, как ваша. Он вызовет AppConfiguration(), чтобы получить экземпляр.

Обратите внимание, что из-за MakeBackboneSingleton последующие все true:

var instance1 = AppConfiguration(); 
var instance2 = new AppConfiguration(); 
instance1 === instance2; // true 
instance1 === AppConfiguration() // true 

автоматически fetch при условии Модель id, но только после того, как мы завершили AppConfiguration «s выборки. Обратите внимание, что вы можете использовать always, then, done и т.д.

var DependentModel = Backbone.Model.extend({ 
    initialize: function() { 
     AppConfiguration().deferred.then(function() { 
      if (this.id) 
       this.fetch(); 
     }); 
    }, 
    url: function() { 
     return AppConfiguration().get('base') + '/someEndpoint'; 
    } 
}); 

Теперь, наконец, положить все это вместе, вы можете создать экземпляр некоторые модели.

var newModel = new DependentModel(); // no id => no fetch 

var existingModel = new DependentModel({id: 15}); // id => fetch AFTER we have an AppConfiguration 

Второй будет автоматически получать до тех пор, как AppConfiguration «s выборки был успешным.

Вот MakeBackboneSingleton для вас (опять-таки из репозитория GitHub):

var MakeBackboneSingleton = function (BackboneClass, options) { 
    options || (options = {}); 

    // Helper to check for arguments. Throws an error if passed in. 
    var checkArguments = function (args) { 
     if (args.length) { 
      throw new Error('cannot pass arguments into an already instantiated singleton'); 
     } 
    }; 

    // Wrapper around the class. Allows us to call new without generating an error. 
    var WrappedClass = function() { 
     if (!BackboneClass.instance) { 
      // Proxy class that allows us to pass through all arguments on singleton instantiation. 
      var F = function (args) { 
       return BackboneClass.apply(this, args); 
      }; 

      // Extend the given Backbone class with a function that sets the instance for future use. 
      BackboneClass = BackboneClass.extend({ 
       __setInstance: function() { 
        BackboneClass.instance = this; 
       } 
      }); 

      // Connect the proxy class to its counterpart class. 
      F.prototype = BackboneClass.prototype; 

      // Instantiate the proxy, passing through any arguments, then store the instance. 
      (new F(arguments.length ? arguments : options.arguments)).__setInstance(); 
     } 
     else { 
      // Make sure we're not trying to instantiate it with arguments again. 
      checkArguments(arguments); 
     } 

     return BackboneClass.instance; 
    }; 

    // Immediately instantiate the class. 
    if (options.instantiate) { 
     var instance = WrappedClass.apply(WrappedClass, options.arguments); 

     // Return the instantiated class wrapped in a function so we can call it with new without generating an error. 
     return function() { 
      checkArguments(arguments); 

      return instance; 
     }; 
    } 
    else { 
     return WrappedClass; 
    } 
}; 
+0

Нет ли элегантного решения? FTR, [this] (https://github.com/Ibrahim-Islam/gh-blog/blob/master/app/app.js#L32-L40) в настоящее время, как я это делаю. Передача в 'config' после загрузки через конструкторы моделей. – lbrahim

+0

Способы slicker будут включать отмену 'fetch' или' sync' или 'save' или' delete' напрямую. –

+0

Если вы хотите, я могу попытаться показать вам способ сделать это. –

Смежные вопросы