官术网_书友最值得收藏!

Reducing the number of filter variables and grouping logically

The filtering currently uses up three variables, filterFieldfilterQuery, and filterUserState. The only thing that currently links these variables is the name, rather than being in an object of their own to link them systematically. Doing this avoids any ambiguity as to whether they are related to the same component or just coincidentally the same. In the data object, create a new object titled filter and move each variable inside:

      data: {
people: [..],
currency: '$',
filter: {
field: '',
query: '',
userState: '',
}
}

To access the data, update any references of filterField to this.filter.field. Note the extra dot, denoting it is a key of the filter object. Don't forget to update filterQuery and filterUserState references as well. For example, the isActiveFilterSelected method would become:

      isActiveFilterSelected() {
return (this.filter.field === 'isActive');
}

You will also need to update the v-model and v-show attributes in your view—there are five occurrences of the various variables.

While updating the filtering variables, we can take this opportunity to remove one. With our current filtering, we can only have one filter active at a time. This means the query and userState variables are only being used at any one time, which gives us the opportunity to combine these two variables. To do so, we'll need to update the view and application code to cater for this.

Remove the userState variable from your filter data object and update any occurrence of filter.userState in your view to filter.query. Now do a find and replace in your Vue JavaScript code for filter.userState, again replacing it with filter.query

Viewing your app in the browser, it will appear to initially work, being able to filter users by the field. However, if you filter by status, then switch to any other field, the query field won't show. This is because using the radio buttons sets the value to a Boolean which, when trying to convert to lowercase for the query field, fails to do so. To tackle this, we can convert whatever value is in the filter.query variable to a string using the native JavaScript String() function. This ensures that our filtering function can work with any filtering input:

      if(this.filter.field === 'isActive') {
result = (typeof this.filter.query ===
'boolean') ? (this.filter.query ===
person.isActive) : true;
} else {
let query = String(this.filter.query),
field = person[this.filter.field];
if(typeof field === 'number') {
query.replace(this.currency, '');
try {
result = eval(field + query);
} catch(e) {}
} else {
field = field.toLowerCase();
result = field.includes(query.toLowerCase());
}

Adding this to our code now ensures our query data is usable no matter what the value. The issue this now creates is when the user is switching between fields to filter. If you select the Active user and chose a radio button, the filtering works as expected, however, if you now switch to Email, or another field, the input box is prepopulated with either true or false. This instantly filters and will often return no results. This also occurs when switching between two text filtering fields, which is not the desired effect.

What we want is, whenever the select box is updated, the filter query should clear. Whether it is the radio buttons or input box, selecting a new field should reset the filter query, this ensures a new search can begin.

This is done by removing the link between the select box and the filter.field variable and creating our own method to handle the update. We then trigger the method when the select box is changed. This method will then clear the query variable and set the field variable to the select box value.

Remove the v-model attribute on the select box and add a new v-on:change attribute. We will pass a method name into this that will fire every time the select box is updated.

v-on is a new Vue binding that we've not encountered before. It allows you to bind actions from elements to Vue methods. For example, v-on:click is one that is used the most commonly - which allows you to bind a click function to the element. We'll cover more on this in the next section of the book.

Where v-bind can be abbreviated to just a colon, v-on can be shortened to an @ symbol, allowing you to use @click="", for example:

      <select v-on:change="changeFilter($event)"     
id="filterField">
<option value="">Disable filters</option>
<option value="isActive">Active user</option>
<option value="name">Name</option>
<option value="email">Email</option>
<option value="balance">Balance</option>
<option value="registered">Date
registered</option>
</select>

This attribute is firing the changeFilter method on every update and passing it the $event data of the change. This default Vue event object contains a lot of information that we could utilize, but the target.value data is the key we are after. 

Create a new method in your Vue instance that accepts the event parameter and updates both the query and field variables. The query variable needs to be cleared, so set it to an empty string, whereas the field variable can be set to the value of the select box:

      changeFilter(event) {
this.filter.query = '';
this.filter.field = event.target.value;
}

Viewing your application now should clear whatever the filter query is, while still operating as expected.

主站蜘蛛池模板: 台北县| 南漳县| 湟中县| 黎平县| 呼图壁县| 邯郸县| 龙海市| 苍溪县| 汾西县| 舟曲县| 高青县| 元朗区| 涞源县| 高密市| 崇州市| 江孜县| 临漳县| 平定县| 浦东新区| 济阳县| 克山县| 武汉市| 丰都县| 湘阴县| 霞浦县| 二连浩特市| 东乌| 沈丘县| 陕西省| 分宜县| 富源县| 鲁山县| 锦屏县| 屏南县| 灵山县| 武胜县| 苍溪县| 九江县| 禹城市| 右玉县| 旬邑县|