angular——ManagerSystem

本文深入探讨了Angular框架中的核心概念——路由与组件,详细介绍了如何创建组件和服务,配置路由,以及实现表单数据绑定。文章还讲解了如何利用Angular的特性进行数据验证和跳转,并介绍了路由守卫和管道等高级功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

component

组件
在这里插入图片描述

service

服务,处理请求数据,解决DRY,
类似于Vuex

在这里插入图片描述

Exercise

  • npm i
  • npm install bootstrap@4.0.0-alpha.6 tether jquery --save
  • 进入package.json将版本号前的^去掉
  • 创建component ng g c
  • router
import { RouterModule,Routes } from '@angular/router';
const Routes: Routes = [
{
	path:'',component:class类名
}
]

@ngModule({
	imports:[
		RouterModule.forRoot(Routes)
	]
})

app.component.html中

<router-outlet></router-outlet>

以及<a routerLink='component名'></a>
在navbar.component.html中设置routerlink实现点击跳转
在这里插入图片描述

  • service
    创建service ng g s service/user
    在app.module.ts中引入
import { UserService } from './services/user.service';

@ngModule({
	providers: [
		UserService,
	]
})
  • http
    在user.service.ts下引入http进行数据获取
import { Http } from '@angular/http';

constructor中声明http

 constructor(
  	  public http:Http
  	) { }
  • 数据获取,观察者,需要引入rxjs
import { map } from 'rxjs/operators';

将获取的数据转成json返回

getUser(){
	return this.http.get("http://localhost:3000/users" )
	.map(res => res.json())
}
  • subscribe ,获取api获得到的数据
    先引入UserService,然后在ngOnInit中获取数据,在页面进入就获到数据。
import { UserService } from '../../services/user.service' 

users:any[];
constructor(
	public userService:UserService
) { }
ngOnInit(){
	this.userService.getUsers()
	.subscribe(users => this.users = users)
}
  • 判断用户信息是否存在,如果不存在提示noUser
    首先用*ngIF进行判断
    ngIf then 和 else 模板
    then 模板除非绑定到不同的值,否则默认是 ngIf 指- 令关联的内联模板。
    else 模板除非绑定对应的值,否则默认是 null。
<table *ngIf="users?.length>0;else noUsers"></table>

使用模板参考变量#noUsers

<ng-template #noUsers>
	<hr>
	<h5>系统中还没有任何用户</h5>
</ng-template>
  • form
    在app.module.ts中引入import { FormsModule } from '@angular/forms';
<div class="form-group">
				<label for="balance">收支</label>
				<input 
					type="text"
					class="form-control"
					[(ngModel)]="user.balance"
					name="balance"
					[disabled]="disableBalanceOnAdd"
				/>
			</div>

[(ngModel)]数据绑定
[diasbled]控制是否禁用

export interface User{
	id?:number;
	name?:string;
	email?:string;
	phone?:string;
	balance?:number;
}

?:用于定义的时候可写可不写某一个属性

  • form表单提交,#f="ngForm"可以获取表单数据
<form #f="ngForm" (ngSubmit)="onSubmit(f)">
			<div class="form-group">
				<label for="name">姓名</label>
				<input 
					type="text"
					class="form-control"
					[(ngModel)]="user.name"
					name="name"
					minlength="2"
					required 
				/>
			</div>

onSubmit传递的参数有两个,value值为ngForm的表单数据,validrequired配合使用,用来进行数据验证。
minlength用于限制输入值的长度
在add-user.component.ts中写onSubmit函数

onSubmit({value,valid}:{value:User,valid:boolean}){
  	// console.log(value);
  	if (!valid) {
  		// console.log("验证失败");
  	}else{
  		// console.log("验证成功!");
  		})  		
  	}
  }
  • 路由指定相对路线
    如果验证成功,跳转到指定的首页,用this.router.navigate进行跳转
 this.router.navigate(['/'], { relativeTo: this.route });

该对象的relativeTo属性设置ActivatedRoutethis.route

  • routerLink 属性绑定带参数跳转
    在app.module.ts中跳转到指定用户详情页路由设置
{path:"user/:id",component:UserDetailComponent},

在users.component.ts中通过拼接方式改变id的值
需要属性绑定routerLink

<td><a [routerLink]="['/hero', hero.id]"></a></td>
  • 获取路由参数id
    需要在user-detail.component.ts中引入ActivatedRouteParams
import { RActivatedRoute,Params } from '@angular/router';

constructor中定义声明ActivatedRoute

  constructor(
  		public route:ActivatedRoute,
  	) { }

获取参数id

this.id = this.route.snapshot.params["id"];

扩展:
$ 是一个命名惯例,用来表明hero$是一个 Observable,而不是数组。 *ngFor 不能直接使用 Observable

ngOnInit() {
  this.hero$ = this.route.paramMap.pipe(
    switchMap((params: ParamMap) =>
      this.service.getHero(params.get('id')))
  );
}

ngOnInit()方法中,使用ActivatedRoute服务检索路由id的参数,从参数中提取数据,然后检索要显示的数据。

  • 登录引导-路由守卫CanActivate
    需要新建一个auth.guard.ts文件,引入以下
import { Injectable } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import { CanActivate, Router } from '@angular/router';
import { Observable } from 'rxjs/Rx';
import { map } from "rxjs";

继承CanActivate

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(
      public afAuth:AngularFireAuth,
      public router:Router
      ) { }
//实现canActivate方法,返回类型为Boolean
  canActivate():Observable<boolean>{
    return this.afAuth.authState.map(auth =>{
      if (!auth) {
       this.router.navigate(["/login"]);
        return false;
      }else {
        return true;
      }
    })
  }
}

在app.module.ts中进行路由守卫设置

const appRoutes:Routes = [
  {path:"",component:HomeComponent,canActivate:[AuthGuard]},
  {path:"login",component:LoginComponent},
  {path:"register",component:RegisterComponent,canActivate:[RegisterGuard]},
  {path:"add-user",component:AddUserComponent,canActivate:[AuthGuard]},
  {path:"user/:id",component:UserDetailComponent,canActivate:[AuthGuard]},
  {path:"edit-user/:id",component:EditUserComponent,canActivate:[AuthGuard]},
  {path:"settings",component:SettingsComponent,canActivate:[AuthGuard]}
]
  • Pipe

angular6之pipe管道
可以在html声明中显示值转换
可以传参

<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>

可以绑定属性值

template: `
  <p>The hero's birthday is {{ birthday | date:format }}</p>
  <button (click)="toggleFormat()">Toggle Format</button>
`
export class HeroBirthday2Component {
  birthday = new Date(1988, 3, 15); // April 15, 1988
  toggle = true; // start with true == shortDate

  get format()   { return this.toggle ? 'shortDate' : 'fullDate'; }
  toggleFormat() { this.toggle = !this.toggle; }
}
<link name="imu"> <inertial> <mass value="0.1"/> <inertia ixx="1.0" ixy="0" ixz="0" iyy="1.0" iyz="0" izz="1.0"/> </inertial> </link> <joint name="cart_to_imu" type="fixed"> <origin xyz="0.0 0.0 0.0"/> <parent link="cart"/> <child link="imu"/> <dynamics damping="0.0" friction="0.0"/> </joint> <link name="ft_sensor_link"> <inertial> <mass value="0.001"/> <inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001"/> </inertial> </link> <joint name="ft_sensor_joint" type="fixed"> <parent link="cart"/> <child link="ft_sensor_link"/> <origin xyz="0 0 0" rpy="0 0 0"/> </joint> <gazebo reference="imu"> <sensor name="cart_imu_sensor" type="imu"> <always_on>1</always_on> <update_rate>10.0</update_rate> </sensor> </gazebo> <!-- <gazebo reference="force_torque_sensor"> <sensor name="ft_sensor" type="force_torque"> <always_on>true</always_on> <update_rate>10</update_rate> <plugin filename="libgazebo_ros_ft_sensor.so" name="ft_sensor_plugin"> <topic_name>ft_sensor/data</topic_name> <interface_name>ft_sensor</interface_name> <frameName>force_torque_sensor</frameName> </plugin> </sensor> </gazebo> --> <gazebo reference="ft_sensor_link"> <sensor name="ft_sensor" type="force_torque"> <plugin filename="libgazebo_ros_ft_sensor.so" name="ft_sensor_plugin"> <topic_name>ft_sensor/data</topic_name> </plugin> </sensor> </gazebo> <ros2_control name="GazeboSystem" type="system"> <hardware> <plugin>gazebo_ros2_control/GazeboSystem</plugin> <param name="sensors">ft_sensor</param> <param name="sensors">cart_imu_sensor</param> </hardware> <joint name="slider_to_cart"> <command_interface name="velocity"> <param name="min">-10</param> <param name="max">10</param> </command_interface> <state_interface name="position"/> <state_interface name="velocity"/> <state_interface name="effort"/> </joint> <sensor name="ft_sensor"> <state_interface name="force.x"/> <!-- <state_interface_ name="force.y"/> <state_interface_ name="force.z"/> <state_interface_ name="torque.x"/> <state_interface_ name="torque.y"/> <state_interface_ name="torque.z"/> --> <!-- <param name="frame_id">ft_sensor_link</param> <param name="fx_range">100</param> <param name="fy_range">100</param> <param name="fz_range">100</param> <param name="tx_range">15</param> <param name="ty_range">15</param> <param name="tz_range">15</param> --> </sensor> <sensor name="cart_imu_sensor"> <state_interface name="orientation.x"/> <state_interface name="orientation.y"/> <state_interface name="orientation.z"/> <state_interface name="orientation.w"/> <state_interface name="angular_velocity.x"/> <state_interface name="angular_velocity.y"/> <state_interface name="angular_velocity.z"/> <state_interface name="linear_acceleration.x"/> <state_interface name="linear_acceleration.y"/> <state_interface name="linear_acceleration.z"/> </sensor> </ros2_control> <gazebo> <plugin filename="libgazebo_ros2_control.so" name="gazebo_ros2_control"> <parameters>$(find gazebo_ros2_control_demos)/config/cart_controller_velocity2.yaml</parameters> </plugin> </gazebo> </robot> 提示[gzserver-1] [WARN] [1747561563.842902051] [gazebo_ros2_control]: Skipping sensor in the URDF named 'ft_sensor' which is not in the gazebo model.
最新发布
05-19
### 解决 Gazebo 中 `ft_sensor` 传感器未正确加载到模型的问题 当遇到 `gazebo_ros2_control ft_sensor not in gazebo model warning` 提示时,这通常是由于插件配置不正确或者缺少必要的依赖项引起的。以下是可能的原因以及解决方案: #### 1. **确认 URDF/XACRO 文件中是否正确定义了 FT Sensor 插件** FT Sensor 的功能需要通过特定的 Gazebo 插件实现,该插件由 `libgazebo_ros_ft_sensor.so` 提供支持。在 URDF 或 XACRO 文件中,应确保以下内容被正确声明并初始化: ```xml <gazebo reference="link_name"> <plugin filename="libgazebo_ros_ft_sensor.so" name="ros_gz_force_torque_plugin"> <alwaysOn>true</alwaysOn> <updateRate>100.0</updateRate> <topicName>/wrench/sensor_frame</topicName> <frameName>sensor_link</frameName> <serviceName>/force_torque_service</serviceName> </plugin> </gazebo> ``` 在此配置片段中: - `filename`: 指定用于处理力矩数据的 Gazebo 插件库文件[^5]。 - `reference`: 应匹配实际机器人链中的某个连接名称 (Link Name)[^6]。 - `topicName`, `frameName`, 和其他字段可以根据需求调整以适配具体的通信主题和服务接口。 #### 2. **检查 ROS 控制器管理器配置文件 controller_manager.yaml 是否包含 force-torque-sensor 支持** 对于基于 `ros2_control` 构建的系统来说,还需要进一步验证控制器管理器的相关 YAML 配置文档里是否有如下条目存在: ```yaml controller_manager: ros__parameters: update_rate: 100 # Hz joint_state_broadcaster: type: joint_state_broadcaster/JointStateBroadcaster force_torque_sensor_broadcaster: type: force_torque_sensor_broadcaster/ForceTorqueSensorBroadcaster ``` 这里引入了一个专门负责广播力矩传感信息的新组件——`force_torque_sensor_broadcaster`[^7]。如果没有显式指定此类广播器实例,则可能导致无法正常接收来自模拟环境的数据流。 #### 3. **验证 libgazebo_ros_ft_sensor.so 动态链接库的存在性和可访问性** 正如之前讨论过的那样,核心问题之一可能是找不到预期使用的共享对象文件(`.so`)。因此有必要再次强调如何排查这类资源缺失状况的方法论: - 使用 `find` 或者 `locate` 工具定位目标文件的实际存储位置; - 如果发现确实不存在对应版本号下的二进制产物,则考虑重新编译源码项目或将官方预构建包纳入本地环境中; - 同时记得扩展全局动态链接路径变量(LD_LIBRARY_PATH),使得运行期解析机制能够识别新增加的内容来源[^8]。 #### 4. **启动调试模式观察日志输出细节** 最后,在尝试上述各项修正措施之后仍然存在问题的情况下,建议开启更详细的诊断记录开关以便获取更多上下文线索辅助分析根本原因所在。例如增加 verbosity level 参数传递给 gzserver 可执行程序调用语句结尾处附加 `-v 4` 类似形式标记即代表启用四级别的消息跟踪级别[^9]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值