2013-09-01 4 views
1

У меня, несомненно, отсутствует что-то очевидное здесь. Это первое приложение, которое я создал.Нокаут не отображается на стороне клиента, пока не обновится (Breeze.js)

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

На снимках:

Step One: Страница загружена. Сущность существует без детей:

Step Two: добавляется дочерний объект, и создается дочерний объект. Поскольку вы можете видеть, что в поле выбора нет параметров. Используя плагин Chrome Knockout, я могу видеть, что свойство, которое содержит параметры, которые должны быть отображены, верны.

Step Three: Я нажимаю кнопку «Сохранить» и обновляю страницу. Поле выбора отображается правильно, но важно, что значение, которое заполняет этот поле выбора, совпадает с шагом 2 (проверяется с помощью нокаутного хром-плагина).

HTML:

<section data-bind="with: parent"> 
    <div data-bind="foreach: children"> 
    <select name="propertyOne" 
     data-bind="options: propertyOneOptions, value: propertyOne, optionsText: 'description', optionsCaption: 'Select a Property'"> 
    </select> 
    <br /> 
    </div> 
    <button data-bind="click: $root.addChild">Add Child</button> 
</section> 
<button data-bind="click: save">Save</button> 

вид Модель:

Как вы можете видеть, как в методе initVm и в методе AddChild я заселение child.propertyOneOptions.

app.viewModel = (function (logger, dataservice) { 

    var parent = ko.observable(null); 
    var propertyOneValues = ko.observableArray([]); 

    var vm = { 
    addChild: addChild, 
    parent: parent, 
    save: save, 
    }; 

    initVm(); 

    return vm; 

    function initVm() { 
    propertyOneValues.push({ 
     key: 'key 1', 
     description: 'value 1' 
    }); 
    propertyOneValues.push({ 
     key: 'key 2', 
     description: 'value 2' 
    }); 
    dataservice.getAllParents() 
     .then(function (data) { 
     console.log('Number of parents = ' + data.results.length); 
     if (data.results.length > 0) { 
      parent(data.results[0]); 
     } else { 
      parent(dataservice.createParent()); 
      dataservice.saveChanges().fail(queryFailed); 
     } 
     ko.utils.arrayForEach(parent().children(), function (child) { 
      console.log('Populating Child ' + child.propertyOneOptions().length); 
      ko.utils.arrayForEach(propertyOneValues(), function (value) { 
      child.propertyOneOptions.push(value); 
      }); 
      console.log('Populated Child ' + child.propertyOneOptions().length); 
     }); 
     }).fail(queryFailed); 
    } 
    function queryFailed(error) { 
    console.log('Query failed: ' + error.message); 
    } 
    function save() { 
    dataservice.saveChanges().fail(queryFailed); 
    } 
    function addChild() { 
    var child = dataservice.createChild(parent); 
    console.log('Creating Child ' + child.propertyOneOptions().length); 
    ko.utils.arrayForEach(propertyOneValues(), function (value) { 
     child.propertyOneOptions.push(value); 
    }); 
    console.log('Populated Child ' + child.propertyOneOptions().length); 
    } 
})(app.logger, app.dataservice); 

// Bind viewModel to view in index.html 
ko.applyBindings(app.viewModel); 

Детский Initializer:

propertyOne и propertyOneOptions создаём ветер лица инициализатору:

function childInitializer(child) { 
    child.propertyOne = ko.observable(); 
    child.propertyOneOptions = ko.observableArray(); 
} 

Модель данных:

public class Parent 
{ 
    public Parent() 
    { 
    Children = new List<Child>(); 
    } 
    [Key] 
    public int Id { get; set; } 

    public String OtherProperty { get; set; } 

    public IList<Child> Children { get; set; } 

} 
public class Child 
{ 
    [Key] 
    public int Id { get; set; } 

    public int ParentId { get; set; } 

    [ForeignKey("ParentId")] 
    public Parent Parent { get; set; } 
} 

Update 1

После прочтения this на производительности, я добавил:

parent().children.valueHasMutated(); 

до конца методы AddChild и вещей улучшился, то есть выберите поле ребенка не делает, но есть призрак ребенок ниже правильного ребенок: Updated Step Two

+0

Я добавил операторы отладки в options.init и options.update ko bindings, как и ожидалось, когда я нажимаю обновление, они вызываются правильно, но когда я нажимаю кнопку add, это не так. –

+0

Как выглядит 'dataservice.createChild (parent)'? Добавляет ли он созданный дочерний элемент в родительский список? – mhu

ответ

0

Вам никогда не придется вызывать valueHasMutated. Я никогда не сталкивался с ситуацией, когда это было действительно необходимо. Проблема, скорее всего, в том, что вы не загрузили все свойства, прежде чем уведомлять нокаута о добавленной сущности, и когда он пытается связать привязку, ломается.

function addChild() { 
    // Don't pass a parent into createChild yet 
    var child = dataservice.createChild(); 
    // After the entity is created, then assign the parent property 
    child().parent(parent()); 
    console.log('Creating Child ' + child.propertyOneOptions().length); 
    ko.utils.arrayForEach(propertyOneValues(), function (value) { 
     child.propertyOneOptions.push(value); 
    }); 
    console.log('Populated Child ' + child.propertyOneOptions().length); 
    } 

Это всегда работает для меня.

+0

Спасибо, отлично работает! Спасибо! –

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