2013-04-23 4 views
1

개체의 속성 초기 값으로 select를 채우는 데 문제가 있습니다.KnockoutJS를 사용하여 선택의 초기 값 설정

나는 urls의 모음 인 속성을 가진 Location 개체를 가지고 있습니다.

{ id: 1, name: 'Location1', state: 'md', headline: 'headline1', urls: [{ id: 1, url: 'www.google.com', type: { id: 1, type: 'Public'} }]} 

사용자가 나는 목록에서 선택한 옵션으로 url.type.type를 표시하기 위해 노력하고있어하지만 항상 optionsCaption을 보여주는 Location을 선택합니다.

여기 내이 fiddle

var seedData = [ 
    { id: 1, name: 'Location1', state: 'md', headline: 'headline1', urls: [{ id: 1, url: 'www.google.com', type: { id: 1, type: 'Public'} }]}, 
    { id: 2, name: 'Location2', state: 'va', headline: 'headline2', urls: [{ id: 1, url: 'www.bing.com', type: { id: 2, type: 'Private'} }]}, 
    { id: 3, name: 'Location3', state: 'md', headline: 'headline3', urls: [{ id: 1, url: 'www.yahoo.com', type: { id: 1, type: 'Public'} }]} 
]; 

function UrlType(data) { 
    this.id = ko.observable(data.id); 
    this.type = ko.observable(data.type); 
} 

function Url(data) { 
    this.id = data.id; 
    this.url = ko.observable(data.url); 
    this.type = ko.observable(new UrlType(data.type)); 
} 

function Location(data, types, names) { 
    var self = this; 

    self.id = data.id; 
    self.name = ko.observable(data.name).extend({ maxLength: 10, unique: { collection: names, externalValue: true } }); 
    self.state = ko.observable(data.state).extend({ pattern: '^[A-Za-z]{2}$'}); 
    self.headline = ko.observable(); 
    self.urls = ko.observableArray(ko.utils.arrayMap(data.urls, function(item) { 
     return new Url(item); 
    })); 
    self.errors = ko.validation.group(self); 

    //update the data at any time 
    self.update = function(data) { 
     self.name(data.name); 
     self.state(data.state); 
     self.headline(data.headline); 
     debugger; 
     self.urls(ko.utils.arrayMap(data.urls, function(item){ 
      return new Url(item); 
     })); 
    }; 

    //initialize with our initial data 
    self.update(data); 
}; 

function ViewModel() { 
    var self = this; 

    self.types = [ 
     { id: 1, name: 'Public' }, 
     { id: 2, name: 'Private' } 
    ]; 

    self.locations = ko.observableArray([]); 

    self.selectedLocation = ko.observable(); 
    self.selectedLocationForEditing = ko.observable(); 

    self.names = ko.computed(function(){ 
     return ko.utils.arrayMap(self.locations(), function(item) { 
      return item.name(); 
     }); 
    }); 

    self.edit = function(item) { 
     self.selectedLocation(item); 
     self.selectedLocationForEditing(new Location(ko.toJS(item), self.types, self.names())); 
    }; 

    self.cancel = function() { 
     self.selectedLocation(null); 
     self.selectedLocationForEditing(null); 
    }; 

    self.update = function(item) { 
     var selected = self.selectedLocation(), 
      updated = ko.toJS(self.selectedLocationForEditing()); //get a clean copy 

     if(item.errors().length == 0) { 
      selected.update(updated); 
      self.cancel(); 
     } 
     else 
      alert("Error");   
    }; 

    self.locations(ko.utils.arrayMap(seedData, function(item) { 
     return new Location(item, self.types); 
    })); 
} 

ko.applyBindings(new ViewModel()); 

답변

0

에 전체 예를 찾아주세요하는 작업 바이올린입니다 : http://jsfiddle.net/jearles/2HS5J/5/

내가 선택한 옵션으로 그냥 속성을 끌어 optionsValue: 'id'을 도입했습니다, 그리고에 seedData 감소 type: 1 (유형 객체가 아닌 고유 ID) 만 포함합니다. 이렇게하면 녹아웃을 통해 type$root.types에 쉽게 매핑 할 수 있습니다 (그렇지 않으면 직접해야 할 것입니다). 또한 options 배열에 name 속성이 아닌 'type'속성이 아닌 객체가 포함되어있는 경우 optionsText: 'type'을 사용하고 있습니다. 따라서 이것이 knockout이 해당 옵션을 채울 수없는 이유입니다.