问题:
当组件加载时,似乎没有调用alreadyVotedFor()方法。那是为什么?
我在服务中添加了一些日志记录,但没有记录到控制台。
我想要达到的目的是预先选择用户之前已经做出的选择并阻止他投票两次。
打开浏览器控制台以查看错误。
修改
当前问题记录(component.ts ngOninit()):
NGONINIT this.votes: undefined
SUBSCRIBE COMPLETE this.votes: undefined
CODE:
component.html
<article class="panel panel-default">
<div class="panel-body">
{{ poll.title }}
<br>
<br>
<form #form="ngForm">
<fieldset [disabled]="alreadyVotedFor(-1)">
{{ poll.counter1 }} votes <input type="radio" id="{{ poll.choice1 }}" name="my_radio" value="{{ poll.choice1 }}" (click)="onChoice1(form)" [checked]="alreadyVotedFor(1)"> {{ poll.choice1 }}
<br>
{{ poll.counter2 }} votes <input type="radio" id="{{ poll.choice2 }}" name="my_radio" value="{{ poll.choice2 }}" (click)="onChoice2(form)" [checked]="alreadyVotedFor(2)"> {{ poll.choice2 }}
</fieldset>
</form>
</div>
<footer class="panel-footer">
<div class="author">
{{ poll.username }}
</div>
<div class="config" *ngIf="belongsToUser()">
<a (click)="onEdit()">Edit</a>
<a (click)="onDelete()">Delete</a>
</div>
</footer>
</article>
component.ts
votes: any;
ngOnInit() {
this.pollService.voted(this.poll, localStorage.getItem('userId')).subscribe(
data => {
this.votes = data.votes;
console.log("NGONINIT this.votes: "+ this.votes);
},
err => { console.log("NGONINIT ERROR: "+ err) },
() => { console.log("SUBSCRIBE COMPLETE this.votes: "+ this.votes); }
);
}
alreadyVotedFor(choice: number) {
let result = "";
if (this.votes) {
console.log("THIS.VOTES: "+this.votes);
for (var i = 0; i < this.votes.length; i ++) {
if (this.votes[i].poll == this.poll.pollId) {
result = "disabled";
if (this.votes[i].choice == choice) {
result = "selected";
}
}
}
}
return result;
}
服务
voted(poll: Poll, userID: string) {
const headers = new Headers({'Content-Type': 'application/json'});
return this.http.get('http://localhost:3000/'+userID,{headers: headers})
.map(response => response.json());
}
修改
你觉得这里有什么错吗?
服务
以下是保存用户投票的方法:
voteOn(poll: Poll, userID: string, choice: number) {
var user;
this.http.get('https://voting-app-10.herokuapp.com/'+userID)
.map(response => response.json())
.subscribe(
json => {
user = json,
user.votes.push({poll, choice });
const body = JSON.stringify(user);
const headers = new Headers({'Content-Type': 'application/json'});
const token = localStorage.getItem('token')
? '?token=' + localStorage.getItem('token')
: '';
return this.http.patch('https://voting-app-10.herokuapp.com/user'+token, body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => {
this.errorService.handleError(error);
return Observable.throw(error);
})
.subscribe();
}
)
}
user.model.ts
import { Poll } from '../polls/poll.model';
export class User {
constructor(public email: string,
public password: string,
public votes?: [{poll: Poll, choice : number }],
public firstName?: string,
public lastName?: string
) {}
}
路由/用户
router.get('/:userid', function (req, res, next) {
var userId = req.params.userid;
User.findById(userID, function (err, user) {
const body = JSON.stringify(user);
console.log("USER JSON? :"+body);
return res.json(body) ;
});
});
答案 0 :(得分:1)
<article class="panel panel-default">
<div class="panel-body">
{{ poll.title }}
<br>
<br>
<form #form="ngForm">
<fieldset [disabled]="alreadyVotedFor(-1)">
{{ poll.counter1 }} votes <input type="radio" id="{{ poll.choice1 }}" name="my_radio" value="{{ poll.choice1 }}" (click)="onChoice1(form)" [selected]="alreadyVotedFor(1)"> {{ poll.choice1 }}
<br>
{{ poll.counter2 }} votes <input type="radio" id="{{ poll.choice2 }}" name="my_radio" value="{{ poll.choice2 }}" (click)="onChoice2(form)" [selected]="alreadyVotedFor(2)"> {{ poll.choice2 }}
</fieldset>
</form>
</div>
<footer class="panel-footer">
<div class="author">
{{ poll.username }}
</div>
<div class="config" *ngIf="belongsToUser()">
<a (click)="onEdit()">Edit</a>
<a (click)="onDelete()">Delete</a>
</div>
</footer>
</article>
votes: any;
ngOnInit() {
this.pollService.voted(this.poll, localStorage.getItem('userId')).subscribe(
data => {
this.votes = data.votes;
},
err => { },
() => { }
);
}
alreadyVotedFor(choice: number) {
let result = "";
if (this.votes) {
for (var i = 0; i < this.votes.length; i ++) {
if (this.votes[i].poll == this.poll.pollId) {
result = "disabled";
if (this.votes[i].choice == choice) {
result = "selected";
}
}
}
}
return result;
}
voted(poll: Poll, userID: string) {
return this.http.get('/'+userID)
.map(response => response.json());
}
答案 1 :(得分:1)
您应该选中disabled属性,以便Angular绑定到它。
<fieldset disabled="alreadyVotedFor(-1)">
应该是:
<fieldset [disabled]="alreadyVotedFor(-1)">
答案 2 :(得分:1)
问题取决于这一行:
<fieldset [disabled]="alreadyVotedFor(-1)">
这个功能:
voted(poll: Poll, userID: string, choice: number) {
var user;
this.http.get('/'+userID)
.map(response => response.json())
.subscribe(json => user = json)
var result = "";
for (var i = 0; i < user.votes.length; i ++) {
if (user.votes[i].poll == poll.pollId) {
result = "disabled";
if (user.votes[i].choice == choice) {
result = "selected";
}
}
}
console.log("RESULT:"+result);
return result;
}
此功能通过双向数据绑定链接到HTML的属性。这意味着它始终执行您的代码来评估您的表达式。 考虑到您的代码具有AJAX请求,它会启动无限的AJAX请求。 您应该更改代码以便不是总是触发AJAX请求,而只是第一次触发?只有在表格中的值发生变化后?我不知道您的用例,但您无法以这种方式直接启动HTTP请求,否则它们将始终启动 此外,从错误看,您的JSON答案中有一个类型,这使得无法从浏览器解析。
虽然最好的解决方案是在控制器的init上执行此操作,但考虑到代码,您可以做的最快的更改是将检索到的值存储在服务的属性中,并避免在已经启动的情况下执行另一个请求。 所以代码可以是这样的。
将属性添加到服务result = undefined;
,而不是将其保持为本地。
然后在你当前的voted function change it in this way:
voted(poll: Poll, userID: string, choice: number) {
if (!this.result) {
var user;
this.http.get('/'+userID)
.map(response => response.json())
.subscribe(json => user = json)
for (var i = 0; i < user.votes.length; i ++) {
if (user.votes[i].poll == poll.pollId) {
this.result = "disabled";
if (user.votes[i].choice == choice) {
this.result = "selected";
}
}
}
console.log("RESULT:"+ this.result);
}
return this.result;
}