2014-09-11 3 views
1

Я новичок в мире нокаутов. Я пытаюсь создать очень простой пользовательский интерфейс с одной страницы, используя knockout.js. У меня есть наблюдаемое вызванное «предложение» в моем классе viewModel, и я заполняю это значение из JSON и отображаю его пользователю, используя привязку данных в текстовом поле ввода.knockoutjs наблюдаемый формат

предложение = «Мой первый опыт с Нокаут {0}»

В пользовательском интерфейсе, пользователь также имеет некоторые текстовые поля, где они могут ввести значения.

опыт = «Хорошо»

Эти введенные значения должны получить заменить в пронумерованных параметров в этом предложении.

"Мой первый опыт работы с нокаутом Хорош"

HTML:

  <select data-bind="options: titles, optionsText: 'title', optionsValue: 'backendName', value: selectedTitleId"></select> 
      <input data-bind='text:text/> 

файл расслоения плотным:

var sample = function(){ 
     var self = this; 
     self.selectedTitleId = ko.observable(); 

     self.text = ko.computed(function() { 
     self.displayText = test(self.selectedTitleId(),["hi"]); //This always throws self.selectedTitleId() is not defined: 
     // the real error is parameter[0] is undefined return parameters[0].replace(pattern, function (match, group) { 

     console.log(self.displayText) 
     //My intention is to return "{" + self.displayText + "}" to the user 
     return "{" + self.selectedTitleId() + "}"; //This shows "World is great {0}" 
     }); 
} 
$.getJSON("json/queries.json", function (allData) { 
    var mappedTasks = $.map(allData, function (item) { 
     return new Task(item.DisplayName, item.BackendFieldName, item.QueryType) 
    }); 
    self.titles(mappedTasks); 
}); 

function test() { 
    return sformat.apply(this, arguments); 
} 
    var sformat = (function() { 
    var pattern = /\{\{|\}\}|\{(\d+)\}/g; 
     return function() { 
     var parameters = arguments; 
     return parameters[0].replace(pattern, function (match, group) { 
     var value; 
      if (match === "{{") 
      return "{"; 
      if (match === "}}") 
      return "}"; 
      value = parameters[parseInt(group, 10) + 1]; 
      return value ? value.toString() : ""; 
     }); 
    }; 
})(); 

Как передать эту self.selectedTitleId в виде строки этого метода испытания ? Если я пытаюсь назначить self.selectedTitleId для var, он всегда жалуется, что self.selectedTitleId() не определен.

Мое требование довольно простое, у меня есть это наблюдаемое self.selectedTitleId, в котором есть форматированная строка, и я пытаюсь заменить нумерованные параметры, такие как {0} {1} значениями. Точно так же, как мы видели в String.format в java-мире.

Любая помощь по этому поводу глубоко ценится. Я боролся с этим последние несколько дней.

Спасибо за ваше время!

+0

Где находится 'self'? –

+0

жаль, что я взял кусочки своего кода и собрал его, и я пропустил эту линию. Я только что редактировал строку в моем вопросе. – user3773712

ответ

0

У вас есть несколько проблем:

  1. Призывая наблюдаемым, прежде чем он имеет значение будет возвращать undefined, поэтому вы получаете сообщение об ошибке. Просто инициализировать наблюдаемым в пустую строку (''), чтобы избежать этого:

    self.selectedTitleId = ko.observable(''); 
    
  2. Чтобы правильно привязать к input значение, вам нужно использовать data-bind="value: ..." вместо этого.text доступен на не входные элементах, такие как <p> или <div>, но так как вы работаете с входом, вы должны использовать value связывания:

    <input type="text" data-bind="value: text" /> 
    
  3. Внутри определения функции ko.computed, я думаю, просто используя локальная переменная будет достаточно:

    self.text = ko.computed(function() { 
        // Sidenote: you don't need to pass this function an array: 
        var displayText = test(self.selectedTitleId(), "hi"); 
    
        return "{" + displayText + "}"; 
    }); 
    

Пример:http://jsfiddle.net/4pfhfbqe/1/


Update:

Хорошо, так это выглядит, как в то время как запрос AJAX собирается заселить наблюдаемые массивы, selectedTitleId является undefined. Я бы просто добавил проверку, чтобы проверить, определено ли это наблюдаемое до его обработки:

self.text = ko.computed(function() { 
    if (self.selectedTitleId()) { 
     var text = test(self.selectedTitleId(), "hi", "bye"); 
     return "{" + text + "}"; 
    } 
    return ''; 
}); 
+0

Привет, Андрей, Спасибо за ваш ответ. Я все еще вижу тот же параметр [0], что не определена ошибка. Когда я попытался отладить этот скрипт с помощью firebug, сначала console.log напечатает пустую строку. Второй раз он печатает undefined. Единственное отличие, которое я вижу от вашей скрипки от моей, - это то, как я загружаю входные заголовки. Я обновил свой вопрос, как я загружал значения. – user3773712

+0

Как-то 'self.selectedTitleId()' заканчивается 'undefined' или' null'. Вы можете '' 'его базовое значение с пустой строкой работать после ошибки:' test (self.selectedTitleId() || '', "hi") '. Не уверен, что еще может вызвать его, хотя –

+0

@ user3773712: Хорошо, я думаю, что вижу проблему - значения массива возвращаются * после того, как * нокаут пытается установить 'selectedTitleId'. Поскольку раскрывающийся список пуст в течение секунды секунды, когда привязка ударяет, значение выбранного элемента равно «null». Вы можете использовать обходное решение, которое я разместил выше, чтобы обойти это, или обработать его в функции 'sformat' –