2017-01-10 4 views
0

Моя программа:Нокаут значение данных связываются неправильно при добавлении новой строки динамически

У меня есть таблица данных, которая является наблюдаемый массив наблюдаемых.

  • При переходе от последнего ввода последней строки он добавляет новую строку пустых входов. Фокус устанавливается в первом входе новой строки.
  • Типы пользователей в номере товара; когда вкладка из него делает некоторые проверки по этому номеру пункта и на основе проходит ли эти проверки
    1. он переходит к следующему полю
    2. он возвращается к этому входу и дает сообщение о том, недопустимом вводе и выбирает текст.

Это все работает отлично. Таким образом, пользователь просматривает и вводит все достоверные данные в этой строке, а затем выводит вкладку из последнего ввода и добавляет новую строку. Но это не настройка фокуса на первый вход, и я даже не могу туда щелкнуть, Я предполагаю, что для переменной/переменной установлено значение false. Я не уверен, как вернуть значение true при добавлении новой строки.

Вот мое отношение HTML:

<tbody data-bind="foreach: items">   
     <tr> 
      <td> 
       <div data-bind="if: (itemNo.length < 1)"><input data-bind="value: itemNo, hasFocus: $parent.invalidItem, selected: $parent.invalidItem, event: { blur: $parent.checkItemNo }, attr: { name: 'brochureitems[' + $index() + '].itemNo', id: 'brochureItems_' + $index() + '__itemNo' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control item-id" /></div> 

И вот мое отношение Нокаут:

var itemModel = function (data) { 
     var self = this; 
     self.itemNo = ko.observable(data ? data.itemNo : undefined).extend({ 
      required: { 
       params: true, 
       message: "Item no. required." 
      } 
     }); 
     self.brocCode = ko.observable(data ? data.brocCode : undefined).extend({ 
      required: { 
       params: true, 
       message: "Bro code required." 
      } 
     }); 
     self.itemDesc = ko.observable(data ? data.itemDesc : undefined).extend({ 
      required: { 
       params: true, 
       message: "Item desc required." 
      } 
     }); 
     self.retail = ko.observable(data ? data.retail : undefined).extend({ 
      required: { 
       params: true, 
       message: "Retail required." 
      } 
     }); 
     self.prizeNum = ko.observable(data ? data.prizeNum : undefined).extend({ 
      required: { 
       params: true, 
       message: "Prize num required." 
      } 
     }); 
     self.itemOrder = ko.observable(data ? data.itemOrder : undefined).extend({ 
      required: { 
       params: true, 
       message: "Item order required." 
      } 
     }); 
    } 
var itemsModel = function(items) { 
     var self = this; 
     self.items = ko.observableArray(items); 

     self.invalidItem = ko.observable(true); 
     console.log("focus has been set"); 

     self.checkItemNo = function(data) { 
      console.log("lost focus - " + self.invalidItem()); 
      var itemNo = $.trim(data.itemNo()); 

      if (itemNo != "") { 
       var item = ""; 
       $.each(window.listOfItems, function(i, v) { 
        if (v.No.search(itemNo) != -1) { 
         item = v.Description; 
         return; 
        } 
       }); 
       if(item != "") { 
        var match = ko.utils.arrayFirst(self.items(), function(newItem) { 
         return itemNo === newItem.itemNo; 
        }); 
        console.log("match: " + match); 
        if (!match) { 
         data.itemDesc(item); 
        } else { // item already entered 
         setTimeout(function() { self.invalidItem(true); }, 1); 
         slideDownMsg("Item already entered."); 
         slideUpMsg(3000); 
        } 
       } else { // invalid item # 
        setTimeout(function() { self.invalidItem(true); }, 1); 
        slideDownMsg("Invalid item number."); 
        slideUpMsg(3000); 
       } 
      } 
     }   

     self.submit = function() { 
      //self.showErrors(true); 
      if (viewModel.errors().length === 0) { 
       console.log('Thank you.'); 
       $("#brochureForm").submit(); 
      } 
      else { 
       console.log('Please check your submission.'); 
       viewModel.errors.showAllMessages(); 
       $(".input-validation-error").first().focus(); 
      } 
     } 

     self.addLine = function() { 
      self.invalidItem(true); 
      console.log(self.invalidItem()); 
      self.items.push(new itemModel()); 
      //setTimeout(function() { self.invalidItem(true); }, 1); 
     }; 

Обновлено

ОК, я получил свою скрипку, чтобы работать, как мой местный код Теперь. Fiddle здесь: https://jsfiddle.net/tLfezuu1/8/ Итак, когда пользователь выходит из последнего ввода, он добавляет новую строку пустых входов. Типы пользователей в количестве на первой вкладке ввода и хитов. Он выполняет некоторые проверки этого номера и отправляет фокус на следующий вход, если проверки прошли или отправляет фокус обратно на этот вход, выделяя текст, если проверки не удались.

+0

бы помочь, если вы могли бы опубликовать фрагмент кода, который работает или скрипку. В коде есть некоторые вещи, которые меня беспокоят, но трудно сказать, что именно вызывает проблему ... (например: почему 'setTimeout'? 'ItemNo' наблюдаемый или нет? Почему' $(). focus() '? Почему и' значение' связывают и подписываются на 'blur'?) – user3297291

+0

Спасибо за советы. Я буду работать над тем, чтобы получить скрипку. Тайм-аут необходим, поскольку я узнал из моего последнего вопроса: http://stackoverflow.com/questions/41557273/knockoutjs-hasfocus-implementation-on-dynamically-added-row – dmikester1

+0

'itemNo' является наблюдаемым. Вы говорите об этой строке: '$ (". Input-validation-error "). First(). Focus();'? – dmikester1

ответ

0

itemNo является наблюдаемым, поэтому вы не можете прочитать его, не используя (), если вы не передадите наблюдаемый непосредственно на привязку, которая его разворачивает. Поскольку вы не инициализируете itemNo, он начинается как undefined, и вы не можете читать его длину в любом случае. Поскольку undefined и пустая строка являются ложными, вы можете просто использовать ifnot и if с наблюдаемым.

<div data-bind="ifnot: itemNo">...</div> 
<div data-bind="if: itemNo">...</div> 

https://jsfiddle.net/rwa03vrb/15/

+0

Проблема заключается в том, что после ввода типа itemNo и tab она переключается на версию 'if: itemNo'. – dmikester1

+0

Как вы хотите, чтобы он работал? –

+0

Я хочу, чтобы все предыдущие записи уже загружались для получения readrly attr, и я хочу те, которые динамически добавляются в качестве новых строк, чтобы оставаться редактируемыми и иметь привязки hasFocus и blur. Он должен оставаться версией 'ifnot: itemNo' даже после того, как что-то напечатано и размыто. – dmikester1

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