如何在Knockout.js中使用具有过滤功能的用户输入

时间:2017-01-02 14:54:25

标签: javascript jquery knockout.js

我有一个过滤功能,我想适应用户输入,但我真的不知道该怎么做。我对Knockout很新,所以我很感激你的帮助。

当我点击过滤按钮(见下面的代码)时,我会在输入区域中找到它:

function observable() {
    if (arguments.length > 0) {
        // Write
        // Ignore writes if the value hasn't changed
        if (observable.isDifferent(observable[observableLatestValue], arguments[0])) {
            observable.valueWillMutate();
            observable[observableLatestValue] = arguments[0];
            observable.valueHasMutated();
            return this; // Permits chained assignments
        } else {
            // Read
            ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation
            return observable[observableLatestValue];
        }
}

我想要实现的是在输入区域中写入一个值,单击按钮(现在,稍后将使用提交)并过滤搜索结果。数组employeeList是一个可观察的数组,通过ajax调用(搜索函数)填充。

KO代码:

self.employeeList = ko.observableArray([]);
self.currentFilter = ko.observable();

self.filterEmpl = ko.computed(function () {
            if (!self.currentFilter()) {
                return self.employeeList();
            } else {
                return ko.utils.arrayFilter(self.employeeList(), function (employee) {
                    return employee.DepartmentName == self.currentFilter();
                });
            }
        });

        self.filter = function (value) {
            self.currentFilter(value);

    } //filter

HTML:

<form>
    <input type="text" placeholder="Department" id="department" class="filterInput" data-bind="value: currentFilter" />
    <button data-bind="click: function () { filter(currentFilter) }">Filter</button>
    <br />
    <input type="text" placeholder="Office" class="filterInput" />
    <br />
    <input type="text" placeholder="Skills" class="filterInput lastInput" />
</form>

谢谢!

1 个答案:

答案 0 :(得分:1)

您的filterEmplko.computed。这意味着一旦它使用的observable值之一被更新,它就会自动更新。

在您的情况下,只要self.employeeListself.currentFilter发生变化,它就会更新。

要尝试此操作,请在下面的示例中键入DepartmentNames之一。从输入中删除焦点后,value数据绑定更新currentFilterself.filterEmpl会更新。

&#13;
&#13;
var VM = function() {
  self.employeeList = ko.observableArray([
    { DepartmentName: "Test1", Name: "Employee 1" },
    { DepartmentName: "Test2", Name: "Employee 2" }
  ]);
  self.currentFilter = ko.observable();

  self.filterEmpl = ko.computed(function() {
    if (!self.currentFilter()) {
      return self.employeeList();
    } else {
      return ko.utils.arrayFilter(self.employeeList(), function(employee) {
        return employee.DepartmentName == self.currentFilter();
      });
    }
  });


}

ko.applyBindings(new VM());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<h2>Type "Test1" or "Test2" and blur focus to filter</h2>
<form>
  <input type="text" placeholder="Department" data-bind="value: currentFilter" />
</form>

<h2>All employees:</h2>
<ul data-bind="foreach: employeeList">
  <li data-bind="text: Name"></li>
</ul>

<h2>Filtered employees:</h2>
<ul data-bind="foreach: filterEmpl">
  <li data-bind="text: Name"></li>
</ul>
&#13;
&#13;
&#13;

现在,如果您想在按下按钮时仅过滤 ,则不需要ko.computed。您定义第二个ko.observableArray并从filter函数中写入它。请注意,您不需要传递任何参数; viewmodel已通过currentFilter绑定识别value值。

&#13;
&#13;
var VM = function() {
  self.employeeList = ko.observableArray([
    { DepartmentName: "Test1", Name: "Employee 1" },
    { DepartmentName: "Test2", Name: "Employee 2" }
  ]);
  self.currentFilter = ko.observable();

  self.filterEmpl = ko.observableArray(self.employeeList());
  
  self.filter = function() {
    var result = self.employeeList(),
        filter = self.currentFilter();
    
    if (filter) {
      result = ko.utils.arrayFilter(result, function(employee) {
        return employee.DepartmentName == filter;
      });
    }
    
    self.filterEmpl(result);
  };


}

ko.applyBindings(new VM());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<h2>Type "Test1" or "Test2" and tap button to filter</h2>
<form>
  <input type="text" placeholder="Department" data-bind="value: currentFilter" />
  <button data-bind="click: filter">filter</button>
</form>

<h2>All employees:</h2>
<ul data-bind="foreach: employeeList">
  <li data-bind="text: Name"></li>
</ul>

<h2>Filtered employees:</h2>
<ul data-bind="foreach: filterEmpl">
  <li data-bind="text: Name"></li>
</ul>
&#13;
&#13;
&#13;

就个人而言,我喜欢使用computed方法。如果性能有限,您可以使用rateLimit选项扩展observable。最终,它主要是用户体验决策。

P.S。您在输入区域中获得的输入是淘汰ko.observable函数的定义。在<button>,您通过currentFilter而未使用currentFilter()获取其值。在filter中,您将此内容写入currentFilter,该<input>数据绑定到if ($request->getMethod() === 'POST') { $form->bind($request); if ($form->isValid()) { $tokenGenerator = $this->get('fos_user.util.token_generator'); $password = substr($tokenGenerator->generateToken(), 0, 8); $user->setEnabled(false); $user->setPlainPassword($password); /** @var $dispatcher EventDispatcherInterface */ $dispatcher = $this->container->get('event_dispatcher'); $event = new GetResponseUserEvent($user, $request); $userManager->updatePassword($user); $userManager->updateUser($user); $em->persist($user); $em->flush(); // Is this isn't supposed to send an email to the newly created user asking to change his password ? $dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_REQUEST, $event); return new RedirectResponse($this->generateUrl('some_url')); } } 。我认为解释这两种方法更有用,但你仍然可能想知道奇怪的输入来自哪里......