2013-07-10 39 views
3

我一直在使用Knockout玩,並且我不知道如何處理這個scenerio。從彈出的菜單中添加一個項目到一個可觀察的數組

基本上我有一個員工名單,你可以從一個選擇控制中爲該員工選擇一個職位。我創建了一個使用jQuery的小彈出窗口,以便用戶可以添加一個新的位置。然後這將更新底層頁面中的選擇。我可以調用viewmodel的addPosition方法,該方法添加了一些新的位置和一些測試數據,但我不知道如何從彈出窗口的文本字段中的值填充它。

這裏是我的小提琴

http://jsfiddle.net/ricobano/HA5uz/3/

<div id="employeeWrapper"> 
    <div data-bind="foreach: employees"> 
     <div> 
      <label>Full Name</label> 
      <input type="text" data-bind="value: fullName" /> 
      <label>Position</label> 
      <select id="slTest" data-bind="options: $root.Positions, value:position, optionsText:'name'"></select> 
      <label>Salary:</label><span data-bind="text: position().formatted"></span> 
     </div> 
    </div> 
    <button id="button" data-bind="click: addEmployee">Add Employee</button> 
    <button id="AddPosition" data-bind="click: open">Add Position</button> 
</div> 

<div data-bind="dialog: {autoOpen: false, title: 'Dialog test' }, dialogVisible: isOpen"> 
    <div> 
     <label>Name:</label><input type="text"/> 
    </div> 
    <div> 
     <label>salary:</label><input type="text"/> 
    </div> 
    <button data-bind="click: addPosition">Add</button> 
</div> 

我的繼承人視圖模型

ko.bindingHandlers.dialog = { 
    init:function(element, valueAccessor, allBindingsAccessor){ 
     var options = ko.utils.unwrapObservable(valueAccessor()) || {}; 
     setTimeout(function() { 
       options.close = function() { 
        allBindingsAccessor().dialogVisible(false);       
       }; 

       $(element).dialog(options);  
      }, 0); 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor) { 
      var shouldBeOpen = ko.utils.unwrapObservable(allBindingsAccessor().dialogVisible), 
       $el = $(element), 
       dialog = $el.data("uiDialog") || $el.data("dialog") 

      //don't call open/close before initilization 
      if (dialog) { 
       $el.dialog(shouldBeOpen ? "open" : "close"); 
      } 
     } 
}; 

function Employee(fullname, position) { 
    var self = this; 
    self.fullName = ko.observable(fullname); 
    self.position = ko.observable(position); 
}; 

function Position(data) { 
    var self = this; 
    self.id = ko.observable(data.id); 
    self.name = ko.observable(data.name); 
    self.salary = ko.observable(data.salary); 

    self.formatted = ko.computed(function(){ 
     return "£" + self.salary(); 
    }); 
}; 

function EmployeeVM() { 
    var self = this; 
    self.employees = ko.observableArray(); 
    self.Positions = ko.observableArray([]); 
    self.isOpen = ko.observable(false); 

    var PositionsJSON = { 
     json: $.toJSON([{ 
      "id": 1, 
      "name" : "No position", 
      "salary" : 0 
     },{ 
      "id": 2, 
      "name" : "Web Developer", 
      "salary" : 15000   
     },{ 
      "id": 3, 
      "name" : "Manager", 
      "salary" : 30000   
     }]) 
    }; 

    var data = { 
     json: $.toJSON([{ 
      "fullName": "Richard Banks", 
       "position": { 
        "id": 2 
      } 
     }, { 
      "fullName": "Dave Grohl", 
       "position": { 
        "id": 3 
      } 
     }, { 
      "fullName": "bobby rahul", 
       "position": { 
        "id": 3 
      } 
     }]) 
    }; 

    $.when(
     $.ajax({ 
      url: "/echo/json/", 
      data: PositionsJSON, 
      type: "POST" 
     }), 
     $.ajax({ 
      url: "/echo/json/", 
      data: data, 
      type: "POST" 
     }) 
    ).done(function(positionArgs, EmployeeArgs){ 
     var ps = $.map(positionArgs[0], function(item){ 
      return new Position(item); 
     }); 

     self.Positions(ps); 

     $.each(EmployeeArgs[0], function (i, item) { 
      var p = ko.utils.arrayFirst(self.Positions(), function(p){ 
       return p.id() == item.position.id; 
      }); 

      var e = new Employee(item.fullName, p); 
      self.employees.push(e); 
     }); 
    }); 

    self.addPosition = function(){ 
     self.Positions.push(new Position({id:"4", name:"Director", salary:"To much"})); 
     self.isOpen(false); 
    }; 

    self.addEmployee = function(){ 
     self.employees.push(new Employee("", self.Positions[0])); 
    }; 

    self.open = function(){ 
     self.isOpen(true); 
    }; 
} 

ko.applyBindings(new EmployeeVM()); 

回答

4

理查德,你幾乎沒有。

使用空白位置模型並將其綁定到對話框中的輸入。 (每個打開的對話框時,一定要空出這種模式的價值。)

function EmployeeVM() { 
    var self = this; 
    ... 
    self.dialogPosition = new Position({id:'',name:'',salary:''}) 
}; 

(綁定...)

<div data-bind="dialog: {autoOpen: false, title: 'Dialog test' }, dialogVisible: isOpen"> 
    <!-- ko with: dialogPosition --> 
    <div> 
     <label>Name:</label><input type="text" data-bind="value:name"/> 
    </div> 
    <div> 
     <label>salary:</label><input type="text" data-bind="value:salary"/> 
    </div> 
    <!-- /ko --> 
    <button data-bind="click: addPosition">Add</button> 
</div> 

當對話框的「添加」按鈕關閉,複製該位置對象並將複製複製到您的self.Positions()可觀察數組中。這將自動更新您的選擇。

self.addPosition = function(){ 
    var newPosition = new Position({id:'',name:self.dialogPosition.name(),salary:self.dialogPosition.salary()}); 
    self.Positions.push(newPosition); 
    self.isOpen(false); 
} 

我已經更新了你的小提琴(不清除對話位)http://jsfiddle.net/HA5uz/5/

希望它能幫助!

+0

昨天晚上我開車回家的時候,我正在想着這些話,但沒有得到修改我的代碼的機會。感謝您的信息。 –

+1

任何時候理查德。通過我的博客停止更多Knockout技術。 http://RyanRahlf.com –

+0

偉大的回答瑞安!我被封鎖了近一個星期,試圖找出如何做到這一點。我在尋找並且四處詢問,但沒有深入到問題的核心。這樣做! –

相關問題