2013-07-29 2 views
5

Say У меня есть этот массив объектов одного типа:Включите определенное observableArray свойств объектов в наблюдаемом

var people = [ 
    { status: 0, name: "name1"}, 
    { status: 1, name: "name2"} 
]; 

и я хочу быть не только observableArray, но я хочу только наблюдать, скажем, свойство состояния каждого объекта.

Представьте, что сами объекты могут быть добавлены или удалены. Свойство имени любого из этих объектов не изменится, поэтому мне действительно не нужно наблюдать за именем, но статус каждого объекта может измениться, поэтому было бы здорово сделать его видимым.

Можно ли сопоставить его с помощью нокаутных утилит с некоторым сильным синтаксическим хакером или мне нужно либо перебирать каждый объект, либо сопоставлять его свойство статуса с наблюдаемым, либо иметь видимый массив и свойства его объектов?

ответ

5

Вы можете использовать ko.mapping.fromJS

var vm = ko.mapping.fromJS(people,{ 
    create: function(options){  
     return { 
      status : ko.observable(options.data.status), // observable 
      name: options.data.name, // non observable 
     } 
    } 
}); 

Теперь VM является observableArray, который содержит объекты, в которых статус является obsevable и имя является постоянным свойством.

See fiddle

@Patryk:

Вы можете сделать это, если у вас есть много свойств, и вы хотите конвертировать только один в наблюдаемый.

var o = ko.mapping.fromJS(people,{create: function(options){ 
    // clone item 
    var item = ko.utils.extend(options.data, {}); 
    // replace status property by an observable 
    item.status = ko.observable(options.data.status); 
    return item; 
}}); 

See updated fiddle

Вы также можете использовать observe с параметром отображения

var mapping = { 
    create: function (options) { 
     return ko.mapping.fromJS(options.data, {'observe': ["status"]}); 
    } 
}; 
var o = ko.mapping.fromJS(people, mapping); 

See fiddle

Я надеюсь, что это помогает.

+1

И что, если у объекта есть больше свойств, из которых я хочу, чтобы только один был видимым, мне нужно явно перечислять каждое свойство независимо от того, является ли оно наблюдаемым или нет? – patryk

+0

Пришел к чему-то подобному, но ваш способ выглядит более профессиональным: D, что мне интересно снова, - это просто: var vm = ko.mapping.fromJS (data, {}); 'то же, что и' var vm; ko.mapping.fromJS (data, {}, vm); ' – patryk

+0

Первый вызов для начального вызова, а второй для обновления. Обновление «означает», когда вы получаете «свежие» данные от терминала, и вам нужно обновить существующую модель просмотра. – Damien

1

Я предлагаю использовать copy

так что вы можете обеспечить множество свойств, которые вы хотите, чтобы не быть наблюдаемыми.

var mappingPeople = { 
    'copy': ["name"] 
}; 

var mapping = { 
    create: function (opts) { 
     return ko.mapping.fromJS(opts.data, mappingPeople); 
    } 
}; 
var PeopleArr = ko.mapping.fromJS(people, mapping); 

здесь Working Demo

Update

В случае, если необходимо отметить одно свойство, как наблюдаемым, а остальное будете нормальные свойства, то я предлагаю использовать observe.

здесь является обновлением моей Example используя observe

+0

Это все еще заставляет меня перечислить все свойства, которые я не хочу быть наблюдаемыми, которые составляют большинство. Моя цель состояла в том, чтобы назвать только те, которые я хочу наблюдать. Я сделал это так, как предложил Дэмиен, не совсем такой ясный и нокаутный, но это сработало. – patryk

+0

@patryk в этом случае вам нужно использовать «наблюдать» http://knockoutjs.com/documentation/plugins-mapping.html#observing_only_certain_properties_using_observe –

+0

@patryk проверить мое обновление –

0

Я знаю, этот вопрос старый, но я столкнулся с той же проблемой и нашел простое решение без использования каких-либо плагинов.

Предположим, вы выполняете запрос на получение и получаете массив сообщений.Для каждой записи у вас есть свойство «Избранное», которое является логическим, указывающим, является ли почта предпочтительной для пользователя или нет, и вы хотите сделать это свойство наблюдаемым, чтобы вы могли работать в некоторой функции, которая меняет свое состояние.

Вы можете сделать следующее:

function ViewModel() { 
    var self = this; 
    self.posts = ko.observableArray([]); 

    $.getJSON("/api/getPosts", function(data) { 
    ko.utils.arrayForEach(data, function(post) { 
    post.Favorited = ko.observable(post.Favorited) 
    }); 
    self.posts(data) 
    }); 
} 

Таким образом, вы включите Избраное свойство наблюдаемого с его значением, и вы можете превратить любое свойство наблюдаемым делать то же самое внутри метода arrayForEach.

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