2016-05-15 4 views
3

Что такое синтаксис (при условии, что он есть), передать элемент управления value в функцию viewmodel? В моем сценарии мне не интересно привязывать значение ввода к свойству viewmodel. Мне просто нужно воздействовать на значение, введенное во входной элемент управления (в основном я повторяю набор элементов и отфильтровываю те, которые не содержат введенный текст).Передача значения входного элемента в качестве параметра функции viewmodel

<input data-bind="text: filterText($data), valueUpdate: 'afterkeydown'"> 

Я попытался filterText($data, value) но Knockout пытается найти value собственности на ViewModel. Мне действительно нужно текущее значение из элемента управления ввода.

Возможно ли это?

ответ

4

Типичный способ обработки этого варианта использования - использовать привязку textInput с подпиской на связанное значение, которое вызывает filterText.

<input data-bind="textInput: filter"> 

В вашем скрипте:

filter.subscribe(function(newValue) { 
    filterText(newValue) 
}); 

который можно упростить:

filter.subscribe(filterText); 

Но вы все еще, вероятно, думал об этом неправильно. Отфильтрованный список должен быть вычислен, который ссылается на значение textInput-bound filter для вычисления отфильтрованного списка.

filteredList = ko.pureComputed(function() { 
    // return the list filtered by the bound filter() value 
}, self); 

Затем вы можете использовать filteredList() везде, где требуется отфильтрованный список данных.

0

Если вы не связываете это свойство с моделью просмотра, вы можете использовать jquery/javascript, чтобы получить значение этого элемента управления ввода непосредственно внутри вашей функции view-model, выполнив что-то вроде этого.

self.Filter= function() {   
    var filter = $('#textBoxID').val(); 
    //  
} 

Таким образом, вам не нужно передавать значение в параметр функции модели представления.

+0

Почему при голосовании без причины? – pso

+0

Это не будет работать с кодом представления OP, который имеет привязку «text». Кроме того, предполагая привязку «значение», это решение будет технически работать, но это не идиоматический KnockoutJS, полагающийся на побочный эффект того, как KO работает внутри, и вызывает проблемы в будущем по моему опыту. – Jeroen

+0

Но парень заявил: «В моем сценарии меня не интересует привязка значения ввода к свойству на viewmodel». Мое решение работает для его сценария, я считаю. – pso

1

Прежде всего. В вашем примере кода используется a text binding на узле input, что не так уж и полезно (это означало бы, что односторонний привязку от модели представления до DOM, «текстовое» содержимое этого input, что не имеет смысла). Учитывая valueUpdate обязательный подарок, вероятно, вы имели в виду the value binding? Заметьте, кстати, что the textInput binding - это способ объединить эти два в современных версиях KnockoutJS.

Что касается вашего фактического вопроса, отсутствует важный контекст: Почему Вы (думаете, что хотите) хотите сделать это? В зависимости от контекста решение будет другим, или вы даже можете получить XY-problem.

В любом случае, к ответам.

Вариант 1
Попытки ответить на конкретный вопрос, тем не менее, я второй @JohnnyHK's answer написания .subscribe на ваших наблюдаемом в качестве одного из возможных решений.

Вариант 2
Другое возможное решение близко напоминающее один, но пытается удовлетворить «Я не заинтересован в значение сторон исходного», то я предлагаю использовать только для чтения вычислен наблюдаемым:

function Root() { 
 
    var self = this; 
 
    
 
    self.filter = ko.computed({ 
 
    read: function() { return ""; }, // <-- not recommended, read context! 
 
    write: function(newValue) { 
 
     // You're free to discard the newValue <-- not recommended, read context! 
 
     alert("Input has been changed."); 
 
    } 
 
    }); 
 
} 
 

 
ko.applyBindings(new Root());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 
<input data-bind="textInput: filter">

Теперь это явно отбрасывает newValue в бит записи (по вашему запросу), и, таким образом, также га с необычной функцией read. Я не рекомендую это, и вместо этого рекомендовал бы использовать закрытую переменную с поддержкой наблюдения для чтения и записи. Эффективно, хотя, это сделает этот вариант эквивалентным первому варианту из другого ответа.

Интересно отметить, однако, немного ваш вопрос о «в collectin» и фильтрации входных данных: если вы посмотрите на the docs from writeable computeds вы обнаружите, что прием пользователей входа или нет, если он удовлетворяет некоторое условие фактически вариант использования для этого.

Вариант 3
Что я рекомендую хотя, если перефразировать ваш запрос немного:

Как вы реагируете на inputvalue изменения с идиоматических KnockoutJS, когда ваше действие не будет заботиться о фактическом value?

Для написания пользовательского взаимодействия с DOM существует custom binding handlers. У вас может быть либо тот, который вообще не использует ViewModel, либо тот, который имеет наблюдаемый.

Опция 3.А

ko.bindingHandlers["opacitor"] = { 
 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
 
    $(element).on("keydown", function() { 
 
     $(this).animate({ opacity: 0.05 }, 1000, function() { $(this).animate({ opacity: 1.0 }, 1000); }); 
 
    }); 
 
    } 
 
} 
 

 
ko.applyBindings({});
input { background-color: gold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 

 
<input data-bind="opacitor">

Вариант 3
Или второй вариант, который действительно использует модель представления:

ko.bindingHandlers["opacitor"] = { 
 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
 
    $(element).on("keydown", function() { 
 
     var speed = ko.utils.unwrapObservable(valueAccessor)(); 
 
     $(this).animate({ opacity: 0.05 }, speed, function() { $(this).animate({ opacity: 1.0 }, speed); }); 
 
    }); 
 
    } 
 
} 
 

 
// speed1 and speed2 could also be observables 
 
ko.applyBindings({ speed1: 500, speed2: 2000 });
input { background-color: gold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 

 
<input data-bind="opacitor: speed1"> 
 
<input data-bind="opacitor: speed2">

Недостатком обоих вариантов 3A и 3B является то, что вам нужно написать логику обработки пользовательских событий. Если у вас есть быстрый взгляд на the textInput source from KO, вы увидите, что это нетривиально, чтобы правильно обрабатывать эти вещи кросс-браузером. Таким образом, использование варианта 1 или 2 может быть еще лучше (даже если у вас будет некоторое взаимодействие модели представления, хотя «вам это не интересно»).

Вариант 4
Использование the event binding. Это страдает от тех же недостатков, что и вариант 3, но, тем не менее, может быть простым решением.Вот пример:

function Root(){ 
 
    var self = this; 
 
    self.myFn = function(data, element) { 
 
    console.log(element.target.value); 
 
    return true; 
 
    }; 
 
} 
 

 
ko.applyBindings(new Root());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 
<input data-bind="event: { keyup: myFn }">

Одно тонкое изменение, которое вы увидите в этом последнем, и вопрос, который я хочу закончить с: вы на самом деле не имеют this issue, где вы на самом деле нужно значение и, следовательно, не следует смотреть на afterkeydown, но для другого мероприятия?

1

Используйте $ element.value для доступа к значению ввода.