2015-02-03 4 views
0

Я пытаюсь получить два примера от работы knockout.com, и мне еще предстоит выяснить это. Любая помощь будет принята с благодарностью!Объедините два примера нокаута

http://jsfiddle.net/gZC5k/2863/

При выполнении этого проекта и с помощью отладчика я получаю сообщение об ошибке: неперехваченного ReferenceError: Невозможно обработать связывание «Еогеасп: функция() {возвращение Linesa}» Сообщения: Linesa не определена

Из оригинального примера я сменил строки на линии, чтобы увидеть, не произошло ли что-то еще. Это все еще не понравилось linesa

Моя основная цель - собрать эти два образца вместе. Кнопка «Добавить контакт» работает, но продукт «Добавить» не работает.

Спасибо!

<div class='liveExample'> 

    <h2>Contacts</h2> 
    <div id='contactsList'> 
     <table class='contactsEditor'> 
      <tr> 
       <th>First name</th> 
       <th>Last name</th> 
       <th>Phone numbers</th> 
      </tr> 
      <tbody data-bind="foreach: contactsa"> 
       <tr> 
        <td> 
         <input data-bind='value: firstName' /> 
         <div><a href='#' data-bind='click: $root.removeContact'>Delete</a></div> 
        </td> 
        <td><input data-bind='value: lastName' /></td> 
        <td> 
         <table> 
          <tbody data-bind="foreach: phones"> 
           <tr> 
            <td><input data-bind='value: type' /></td> 
            <td><input data-bind='value: number' /></td> 
            <td><a href='#' data-bind='click: $root.removePhone'>Delete</a></td> 
           </tr> 
          </tbody> 
         </table> 
         <a href='#' data-bind='click: $root.addPhone'>Add number</a> 
        </td> 
       </tr> 
      </tbody> 
     </table> 
    </div> 

    <p> 
     <button data-bind='click: addContact'>Add a contact</button> 
     <button data-bind='click: save, enable: contactsa().length > 0'>Save to JSON</button> 
    </p> 

    <textarea data-bind='value: lastSavedJson' rows='5' cols='60' disabled='disabled'> </textarea> 

</div> 

<div class='liveExample'> 

    <table width='100%'> 
     <thead> 
      <tr> 
       <th width='25%'>Category</th> 
       <th width='25%'>Product</th> 
       <th class='price' width='15%'>Price</th> 
       <th class='quantity' width='10%'>Quantity</th> 
       <th class='price' width='15%'>Subtotal</th> 
       <th width='10%'> </th> 
      </tr> 
     </thead> 
     <tbody data-bind='foreach: linesa'> 
      <tr> 
       <td> 
        <select data-bind='options: sampleProductCategories, optionsText: "name", optionsCaption: "Select...", value: category'> </select> 
       </td> 
       <td data-bind="with: category"> 
        <select data-bind='options: products, optionsText: "name", optionsCaption: "Select...", value: $parent.product'> </select> 
       </td> 
       <td class='price' data-bind='with: product'> 
        <span data-bind='text: formatCurrency(price)'> </span> 
       </td> 
       <td class='quantity'> 
        <input data-bind='visible: product, value: quantity, valueUpdate: "afterkeydown"' /> 
       </td> 
       <td class='price'> 
        <span data-bind='visible: product, text: formatCurrency(subtotal())' > </span> 
       </td> 
       <td> 
        <a href='#' data-bind='click: $parent.removeLine'>Remove</a> 
       </td> 
      </tr> 
     </tbody> 
    </table> 
    <p class='grandTotal'> 
     Total value: <span data-bind='text: formatCurrency(grandTotal())'> </span> 
    </p> 
    <button data-bind='click: addLine'>Add product</button> 
    <button data-bind='click: save'>Submit order</button> 

</div> 

    var initialData = [ 
    { firstName: "Danny", lastName: "LaRusso", phones: [ 
     { type: "Mobile", number: "(555) 121-2121" }, 
     { type: "Home", number: "(555) 123-4567"}] 
    }, 
    { firstName: "Sensei", lastName: "Miyagi", phones: [ 
     { type: "Mobile", number: "(555) 444-2222" }, 
     { type: "Home", number: "(555) 999-1212"}] 
    } 
]; 

var ContactsModel = function(contactstest) { 
    var self = this; 
    self.contactsa = ko.observableArray(ko.utils.arrayMap(contactstest, function(contact) { 
     return { firstName: contact.firstName, lastName: contact.lastName, phones: ko.observableArray(contact.phones) }; 
    })); 

    self.addContact = function() { 
     self.contactsa.push({ 
      firstName: "", 
      lastName: "", 
      phones: ko.observableArray() 
     }); 
    }; 

    self.removeContact = function(contact) { 
     self.contactsa.remove(contact); 
    }; 

    self.addPhone = function(contact) { 
     contact.phones.push({ 
      type: "", 
      number: "" 
     }); 
    }; 

    self.removePhone = function(phone) { 
     $.each(self.contactsa(), function() { this.phones.remove(phone) }) 
    }; 

    self.save = function() { 
     self.lastSavedJson(JSON.stringify(ko.toJS(self.contactsa), null, 2)); 
    }; 

    self.lastSavedJson = ko.observable("") 
}; 

ko.applyBindings(new ContactsModel(initialData)); 

function formatCurrency(value) { 
    return "$" + value.toFixed(2); 
} 

var CartLine = function() { 
    var self = this; 
    self.category = ko.observable(); 
    self.product = ko.observable(); 
    self.quantity = ko.observable(1); 
    self.subtotal = ko.computed(function() { 
     return self.product() ? self.product().price * parseInt("0" + self.quantity(), 10) : 0; 
    }); 

    // Whenever the category changes, reset the product selection 
    self.category.subscribe(function() { 
     self.product(undefined); 
    }); 
}; 

var Cart = function() { 
    // Stores an array of lines, and from these, can work out the grandTotal 
    var self = this; 
    self.linesa = ko.observableArray([new CartLine()]); // Put one line in by default 
    self.grandTotal = ko.computed(function() { 
     var total = 0; 
     $.each(self.linesa(), function() { total += this.subtotal() }) 
     return total; 
    }); 

    // Operations 
    self.addLine = function() { self.linesa.push(new CartLine()) }; 
    self.removeLine = function(line) { self.linesa.remove(line) }; 
    self.save = function() { 
     var dataToSave = $.map(self.linesa(), function(line) { 
      return line.product() ? { 
       productName: line.product().name, 
       quantity: line.quantity() 
      } : undefined 
     }); 
     alert("Could now send this to server: " + JSON.stringify(dataToSave)); 
    }; 
}; 

ko.applyBindings(new Cart()); 
+0

Если я разделить эти два примера в различные примеры они оба работают нормально. – user924092304

ответ

0

ViewModel является ContactsModel, поскольку ContactsModel не обладает свойством Linesa, он не может сделать содержимое таблицы.

<tbody data-bind='foreach: linesa'> 

Это оскорбительная линия.

Вы работаете с 2 ViewModels на самом деле, с ViewModel и с ViewModel контактов.

необходимо создать новый ViewModel, который реализует обе модели ViewModels, и вы можете привязать представления с помощью привязки with.

Код:

function CombinedViewModel(){ 
    this.cart=new Cart(); 
    this.contact=new Contact(); 
} 

ko.appyBindings(new CombinedViewModel()); 

и креплениями

<div data-bind="with:cart"><!-- cart html view goes here --></div> 
<div data-bind="with:contact"><!-- contact html view goes here --></div> 
+0

Большое спасибо! Это имеет смысл! Вот законченное решение в случае, если кто-либо найдет его полезным. http://jsfiddle.net/gZC5k/2881/ – user924092304

+0

Вот обновленный пример с работающими числами. http://jsfiddle.net/gZC5k/2889/ – user924092304

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