Reputation: 2405
I'm programming with angular 1.6 and typescript. In my project i need to load list of users from the server and display the list with checkboxes near each person:
<div class="container">
<h2>Hello {{ $ctrl.name }}</h2>
<ul ng-repeat="user in $ctrl.users" class="list-group">
<li class="list-group-item">
<input type="checkbox" ng-model="user.selected">
{{user.name}}
</li>
</ul>
<button class="btn btn-primary" ng-click="$ctrl.showSelected()">save</button>
</div>
After user selects some persons and clicks the button below he should get alert with list of selected persons.
Here is Person object that comes from server
export class Person {
public name:string;
}
And my Service looks this way:
getUsers() : ng.IHttpPromise<Person[]> {
return this.$http.get('users.json').then((res:ng.IHttpPromiseCallbackArg<Person[]>)=>{
return res.data
})
}
Since in my ui the person elements must have "selected" property - i thinking about create uiPerson class which will derive from Person:
import { UsersService } from './service'
import { Person } from './Person'
class uiPerson extends Person{
public selected:false;
}
export const AppComponent = {
template: `
<div class="container">
<h2>Hello {{ $ctrl.name }}</h2>
<ul ng-repeat="user in $ctrl.users" class="list-group">
<li class="list-group-item">
<input type="checkbox" ng-model="user.selected">
{{user.name}}
</li>
</ul>
<button class="btn btn-primary" ng- click="$ctrl.showSelected()">save</button>
</div>
`,
controller: class AppComponent {
static $inject =["usersService"]
constructor(private usersService: UsersService) { }
$onInit() {
this.name ='Users';
this.usersService.getUsers().then(users=>{
this.users= users as uiPerson[];//<-- HERE IS QUESTION
})
}
showSelected() {
alert(this.users.filter(u=>u.selected).map(u=>u.name).join(','))
}
}
};
I'm new with typescript - am i right about mapping with "this.users= users as uiPerson[]" syntax? Is there some more correct way to do it?
here is the plnkr
Thanks
Upvotes: 0
Views: 79
Reputation: 412
My advice here would be to avoid introducing the uiPerson class - it is adding complexity and polluting your domain model. Is 'selected' truly an attribute of a Person?
What would happen if you were required to present the same Person is two lists?
public selectedList1: boolean;
public selectedList2: boolean;
Instead - I would look to store the 'selected' state in your Controller, exposing a simple 'isSelected' function:
controller: class AppComponent {
static $inject =["usersService"]
constructor(private usersService: UsersService) { }
public selectedUsers: Person[] = [];
$onInit() {
this.name ='Users';
this.usersService.getUsers().then(users=>{
this.users= users; <-- No uiPerson
})
}
showSelected() {
alert(this.selectedUsers.map(u=>u.name).join(','))
}
isSelected(person: Person): boolean {
return selectedUsers.indexOf(person) !== -1;
}
Template:
<input type="checkbox" ng-checked="$ctrl.isSelected(user)">
Upvotes: 1
Reputation: 6029
This looks reasonable to me. I would personally make a couple adjustments:
new
)selected
to be optional, since at first your array of UiPerson objects will not have it defined. That may also allow you to skip the type cast.Here is a revised plunkr with those changes, and I also took the liberty to make it closer to my personal style, in case you like what you see.
Upvotes: 2