2016-03-07 5 views
0

Моя модель данных в формате -как проверить, включены ли вложенные атрибуты в магистральную модели изменились

{ 
    feature1: { 
    enabled: true, 
    default: false 
    }, 
    feature2: { 
    enabled: true, 
    default: false 
    } 
} 

И где-то в моем коде я заходящего как this.model.get("feature1").enabled = false;

Теперь, как я могу проверить, если модель изменила атрибуты, когда формат данных подобен приведенному выше.

+2

он будет работать, чтобы слушать 'изменения' события модели и использовать this.model.set ('feature1', this.model.get ('feature1'). Enabled = ложь) ;?Я не уверен, что способ, которым вы в данный момент меняете атрибут, воспользуется любыми встроенными функциями базового блока. (Если это произойдет, кто-то скоро опубликует ответ :)) [Макет-модель] (http://backbonejs.org/#Model-set) И этот вопрос SO: [Магистральные вложенные атрибуты] (http: // stackoverflow.com/questions/6351271/backbone-js-get-and-set-nested-object-attribute) –

+0

Возможный дубликат [Backbone.js get и set вложенного атрибута объекта] (http://stackoverflow.com/questions/ 6351271/магистральные-JS-получить-и-набор вложенного-объект-атрибут) –

ответ

1

Вы можете привязывать события изменений только к Backbone-моделям к атрибутам верхнего уровня.

Это можно сделать здесь двумя способами, либо создав такую ​​коллекцию моделей, где это можно сделать, либо с помощью плагина с глубокой моделью, такого как https://github.com/kahwee/backbone-deep-model.

Так он стал бы:

var model = new Backbone.DeepModel({ 
    feature1: { 
     enabled: true, 
     default: false 
    }, 
    feature2: { 
     enabled: true, 
     default: false 
    } 
}); 

model.on('change:feature1.* change:feature2.*', function(model, val) { 
    console.log(val); 
}); 

model.set({ 
    'feature1.enabled': false 
}); 

jsbin пример - https://jsbin.com/gatuyadoji/edit?js,console,output

0

Перед показом возможное решение, позвольте мне сказать вам, чтобы рассмотреть, если индивидуальные изменения вложенных атрибутов действительно необходимому. Обновление представления об изменениях функций может не стоить столько времени, сколько вам нужно беспокоиться.

Если только одно представление требует обнаружения изменений атрибутов в вложенных атрибутах модели, возможно, прослушивание события изменения достаточно, так как вы можете обнаружить изменения отдельных атрибутов в событии изменения.

Следующие решения требуют, чтобы обновить весь атрибут, как это:

model.set("feature1", _.extend({ }, model.get("feature1"), { enabled: false })); 

Пожалуйста, refer to this good answer to a similar question.

При изменении модели событие получает три агитации: модель, измененные значения и параметры до set(), а модель сохраняет предыдущие значения - в вашем случае объект объектов - в _previousAttributes.

model.on("change:feature1", function(model, value) { 
    var prev = model._previousAttributes; 

    if (model.get("feature1").enabled !== prev.feature1.enabled) { 
     // update upon change of "enabled" 
    } 

    if (model.get("feature1").default !== prev.feature1.default) { 
     // update upon change of "default" 
    } 
}); 

Поскольку этот код немного громоздким для каждого «элемента» вы можете написать отдельный помощник:

// returns an object which maps a key difference to true to easily check 
// using "key" in obj 
function objDiff(a, b) { 
    var keys = _.union(_.keys(a), _.keys(b)), isDef = {}; 
    _.each(keys, function(key) { 
     if (a[key] !== b[key]) { 
      isDef[key] = true; 
     } 
    }); 
    return isDef; 
} 

И проверить атрибут изменить таким образом:

model.on("change:feature1", function(model, value) { 
    var changed = objDiff(model.get("feature1"), model._previousAttributes.feature1); 

    if ("enabled" in changed) { 
     // update upon change of "enabled" 
    } 

    if ("default" in changed) { 
     // update upon change of "default" 
    } 
}); 

Оба реализация также будет работать, если вы слушаете только change.


Side Примечание: поскольку ваш вопрос задает для обработчиков изменений на определенных атрибутов Я предполагаю, что вы слушаете отдельные атрибуты и обновления частей зрения индивидуально. Рассмотрим разбивку модели на карту, список или базовую коллекцию моделей, которые имеют только атрибуты enabled и default и featurename. Затем ваше представление может отображать и обновлять изменения «featureModelX».

var FeatureModel = Backbone.Model({ 
    defaults: { 
     enabled: false, 
     default: false 
    } 
}); 

new FeatureModel({feature: "feature1"}); 
Смежные вопросы