2013-09-01 47 views
1

我毫無疑問在這裏丟失了一些明顯的東西。這是我創建的第一個前端應用程序。敲擊不渲染客戶端選擇框直到刷新(Breeze.js)

我想要一個客戶端選擇框,當選擇一個選項時,實體上的單獨屬性將被更新。當選擇框被改變時,意味着一個函數被調用,然後適當地更新其他屬性。我遇到的問題是,當在客戶端創建實體時,選擇框不會呈現。

在圖片:

Step One:加載頁面。該實體存在沒有子女:

Step Two:單擊添加子項,並創建一個子實體。正如你所看到的,選擇框沒有選項。使用Chrome Knockout插件,我可以看到包含應該呈現的選項的屬性是正確的。

Step Three:我點擊保存然後刷新頁面。選擇框呈現正確,但重要的是,填充此選擇框的值與第二步相同(通過淘汰賽Chrome插件進行驗證)。

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

兒童初始化程序:

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

更新1

性能閱讀this後,我說:

parent().children.valueHasMutated(); 

到的addChild方法和事情年底有所改善,這是一個孩子的選擇框沒有渲染,但有一個幽靈孩子正確的子下面:Updated Step Two

+0

我按照預期在options.init和options.update ko綁定中添加了調試語句,當我點擊刷新時它們被正確調用,但是當我點擊添加時,它們不是。 –

+0

'dataservice.createChild(parent)'看起來像什麼?它是否將創建的子項添加到父列表中? – mhu

回答

0

你不應該調用valueHasMutated。我從未遇到實際需要的情況。問題很可能是您在通知Knockout添加的實體之前沒有加載所有的屬性,以及它何時試圖綁定綁定正在中斷。

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

謝謝工作完美!謝謝! –