I created a list on each list I've set up a remove method. Every-time I click the list in my jsfiddle I get what I want, but when I attach my project up with vuex it seems like the index is wrong. It just keeps removing the last item on my list no mater where i click. instead of the one i click.
<md-table>
<md-table-row v-for="(opt, index) in this.getAddedSegmentationList" :key="index">
<md-table-cell>
<ul >
<li>Name: API_NEEDS_TO_BE_UPDATED</li>
<li>Created: {{opt.created_time | newTime}}</li>
<li>Finished: {{opt.end_time | newTime}}</li>
</ul>
<ul class="channel-segements__tab-handlers">
<li class="channel-segements__tab-handlers-items" #click="removeSegement(index, opt)">
<md-icon>delete</md-icon>
</li>
</ul>
</md-table-cell>
</md-table-row>
</md-table>
methods: {
removeSegement(index, opt) {
this.getAddedSegmentationList.splice(index, 1)
}
},
computed: {
getAddedSegmentationList() {
return this.$store.state.channels.channelSegmentList
}
},
My original jsfiddle https://jsfiddle.net/ronoc4/eywraw8t/65812/ for testing to make sure it was possible.
Related
There are five buttons. When one of these buttons is clicked, the active class must be added and the others must be deleted. How can I do this with react? Buttons are not links.
enter image description here
<ul>
<li className="active">
All
</li>
<li>
Draft
</li>
<li>
Under assessment
</li>
<li>
Need data
</li>
<li>
Ready
</li>
</ul>
I see you are using className. That probably means you are using react. If you are, then please do not use jquery. JQuery and React do not like each other. JQuery manipulates the dom, whereas React schedules updates to its own virtual dom.
You could do something like this. Create two classes, active and inactive (or whatever you want to call them). Add a click event to it and have that click set the index. Then you can set it as active or not by the index.
const [activeIndex, setActiveIndex] = React.useState(0);
const handleOnClick = index => {
setActiveIndex(index);
};
const boxs = [0, 1, 2, 3];
const box = boxs.map((item, index) => {
return (
<li
key={index}
onClick={() => handleOnClick(index)} // pass the index
className={activeIndex === index ? "active" : "inactive"}
>
{item}
</button>
While this is not the exact code, it represents the issue. I have an object that has a method that returns an array. This array is then updated asynchronously. In the demo it is a timeout but in reality it would be an HTTP call:
function () {
let a = ['apple'];
setTimeout(() => {
a.push['banana'];
}, 3000);
return a;
}
Then it is included in a Vue component via a computed property and displayed, e.g.
<ul>
<li v-for="(row, index) in testObjectArr" v-bind:key="index">
{{row}}
</li>
</ul>
However this only displays the first entry (apple) and not the second (banana). If an event does cause the template to refresh then it does appear.
Using things like watch also doesn't work. The only way to get it working is to pass a handler in to the object that manually triggers a redraw which is oviously less than ideal.
Is there any way to get responsivity to actually work with the above situation?
In order to make variables reactive, you should declare them as such by using ref or reactive. So your code should be:
<script setup>
import { ref } from 'vue';
const items = ref(['apple']);
setTimeout(() => {
items.value.push('banana');
}, 1000);
</script>
<template>
<ul>
<li v-for="(item, index) of items" :key="index">
{{ item }}
</li>
</ul>
</template>
See it live
i am render the array of list using ngFor. i am using infinite scroll and add the new elements on scroll end. but after adding the new elements in array, the render is not happened and it only update when i click on any were in page.
file.html
<div *ngIf="arrayList.length">
<ul class="max-h-400" infinite-scroll (scrollEnd)="onScrollFunc()">
<li *ngFor="let item of arrayList;let i = index">
<div>item.name</div>
</li>
</ul>
</div>
file.ts
onScrollFunc() {
this.getNewElemList(reqObj)
.subscribe(
response => {
if (response && response.data) {
if (this.arrayList && this.arrayList.length) {
this.arrayList.push(...response.data);
} else {
this.arrayList = response.data;
}
}
},
() => {
console.log('error');
}
);
}
The Problem is, change detection does not fire if you push to an array. Since the bound object is the array, the array has to change its refrence.
So instead of arrayList.push do it like this:
this.arrayList = [...this.arrayList, ...response.data]. This creates a new array which triggers the change detection to render again
Here is a ToDoList from Vue examples.
I want to add some extra features to this small app, e.g. set date for task. Therefore I'd like to show more operations of the task when I click "...".
Below is what I want to avoid, which after clicking another task, the previous click action doesn't be removed:
I try to add a property for each todo, and bind a click function on the "..." (more). Each time click "more", firstly set "isMoreClick" property of all task to false, then toggle the value of "isMoreClick" of current clicked task:
<button class="more"
#click="isMoreClick(todo)"
v-show="!todo.isMoreClick">
</button>
<div class="more-opt" v-show="todo.isMoreClick">
<button class="destroy" #click="removeTodo(todo)"></button>
</div>
...
this.todos.push({
id: todoStorage.uid++,
title: value,
completed: false,
isMoreClick: false // this is what I added
})
...
isMoreClick (todo) {
this.todos.forEach(todo => {
todo.isMoreClick = false
})
todo.isMoreClick = !todo.isMoreClick
}
I think my approach is a little stupid. Is there any better solution? (set a flag symbol?)
You don't say how you're rendering the todo elements. But if you're using a v-for loop, one approach could be
<ul>
<li
v-for="(todo, index) in todos"
:key="index"
>
{{todo.whatever}}
<button
v-if="index !== visibleTodoIndex"
class="more"
#click="visibleTodoIndex = index"
/>
<div
v-else
class="more-opt"
>
<button
class="destroy"
#click="visibleTodoIndex = -1"
/>
</div>
</li>
<ul>
Then just add visibleTodoIndex to the component's data.
It looks to me you need to use a global variable accessible from all todos, not to have a local variable inside each todo and updating it everywhere every time. I recommend using vuex store and updating isMoreClick value via mutations.
I'm a newbie in AngularJS and faced with an issue.
Need to create message history tree, which provides expand/collapse functionality on the parent item.
I've created view:
<div class="tree">
<ul>
<li ng-repeat="appt in apptsToFilter() | filter: groupByAppt" ng-click="showChilds()">
<span>{{appt.startTime}} - Appt. Id: {{appt.appointmentId}} </span>
<ul>
<li ng-repeat="item in appts | filter: {appointmentId: appt.appointmentId}" ng-show="active">
<span>{{item.message}}</span>
</li>
</ul>
</li>
</ul>
</div>
This is my controoler for this view:
function MessageHistoryController($scope, $routeParams, MessageHistoryResource) {
......//some code
$scope.active = false;
$scope.showChilds = function() {
if ($scope.active == false) {
$scope.active = true;
} else {
$scope.active = false;
}
};
}
This is what I get, when I've expanded first parent item:
ParentItem2:
- Child1
- Child2
- Child3
ParentItem2
- Child1
- Child2
ParentItem3
- Child1
When I click on any parent item - all of my subtrees expanded or collapsed.
But I expected this result, as below (only clicked item should be expanded):
ParentItem2:
- Child1
- Child2
- Child3
ParentItem2
ParentItem3
Any ideas are appreciated. Thanks.
That's because you have all of your parent, clickable items, set to one boolean. This can be resolved in the HTML without the active bool.
Set your show/hide element to:
ng-show="appt.active"
Then set your click call to:
ng-click="appt.active = !appt.active"
Full Example:
<div class="tree">
<ul>
<li ng-repeat="appt in apptsToFilter() | filter: groupByAppt" ng-click="appt.active = !appt.active">
<span>{{appt.startTime}} - Appt. Id: {{appt.appointmentId}} </span>
<ul>
<li ng-repeat="item in appts | filter: {appointmentId: appt.appointmentId}" ng-show="appt.active">
<span>{{item.message}}</span>
</li>
</ul>
</li>
</ul>
</div>
Even though appt.active would initialize as undefined when clicked it will change to true, at least it does on my end and this is how I handle these cases.
You could also loop through the appt and define active in the javascript.
For future reference you can simplify your $scope.showChilds function to:
$scope.showChilds = function () {
$scope.active = !$scope.active
}