我有一个JHipster应用程序(Angular 5 + Spring Boot 2),我正在尝试为我拥有的模型对象创建一条新路线(不是使用实体生成器创建的,这只是一个简单的模型)。问题是即使我看到Angular应用正在调用正确的API并获得有效的JSON响应,我的组件也没有初始化。
这是模型(简化):
export interface IInstructor {
id?: string;
}
export class Instructor implements IInstructor {
constructor(
public id?: string,
) {}
}
以及加载Instructor
对象的服务:
type EntityResponseType = HttpResponse<IInstructor>;
@Injectable({ providedIn: 'root' })
export class InstructorService {
public resourceUrl = SERVER_API_URL + 'api/instructor';
constructor(private http: HttpClient) {}
get(name: string): Observable<EntityResponseType> {
return this.http.get<IInstructor>(`${this.resourceUrl}/${name}`, { observe: 'response' });
}
}
路线+解析:
@Injectable({ providedIn: 'root' })
export class InstructorResolve implements Resolve<IInstructor> {
constructor(private service: InstructorService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const name = route.params['name'] ? route.params['name'] : null;
if (name) {
return this.service.get(name).pipe(map((instructor: HttpResponse<Instructor>) => instructor.body));
}
return of(new Instructor());
}
}
export const instructorRoute: Routes = [
{
path: 'instructor/:name',
component: InstructorComponent,
resolve: {
ride: InstructorResolve
},
data: {
pageTitle: 'Instructor Details'
}
}
];
最后,组件本身和视图:
export class InstructorComponent implements OnInit {
service: InstructorService;
instructor: IInstructor;
constructor(private instructorService: InstructorService,
private activatedRoute: ActivatedRoute,
private router: Router) {
this.service = instructorService;
}
ngOnInit() {
this.activatedRoute.data.subscribe(({ instructor }) => {
this.instructor = instructor;
console.log('Got instructor = ' + instructor);
});
}
<div id="jhi-instructor">
<div class="row justify-content-center">
<div class="col-lg-8">
<hr/>
<h2>Instructor Details</h2>
<div *ngIf="instructor !== null">
<h2>{{instructor.id}}</h2>
</div>
</div>
</div>
</div>
当我导航到/instructor/somename
时,我可以在Chrome调试器中看到它是对Spring Boot应用程序进行XHR调用,并返回有效的JSON有效负载。但是在InstructorComponent
内部,从未设置instructor
变量。我看到来自ngOnInit
的控制台消息,但是从activatedRoute
返回的对象为空:
Got instructor = undefined instructor.component.ts:27:12
ERROR TypeError: "_co.instructor is undefined"
View_InstructorComponent_1 InstructorComponent.html:1
这是我在应用程序其他部分所遵循的模式(并且基本上已从自动生成的JHipster代码中重复使用),并且效果很好,所以我不确定自己缺少什么。
更新
我怀疑这是人为错误。我已经从其他组件复制了路由,但没有更改解析值(它使用的是 ride 而不是 instructor )。非常感谢您的建议!
resolve: {
instructor: InstructorResolve
},
答案 0 :(得分:1)
我想,进行如下较小的更正可以使您在组件中获得所需的数据。
const routes: Routes = [
{ path: 'instructor/:name',
component: InstructorComponent,
resolve: {
ride: InstructorResolve
},
data: {
pageTitle: 'Instructor Details'
}
}]
然后在组件中进行如下更改。
export class InstructorComponent implements OnInit {
service: InstructorService;
instructor: IInstructor;
constructor(private instructorService: InstructorService,
private activatedRoute: ActivatedRoute,
private router: Router) {
this.instructor = this.route.snapshot.data["ride"];
this.service = instructorService;
}
}
您需要使用组件中路由部分解析所用的相同密钥来检索数据,以便从路由中获取解析的数据。
我希望这会有所帮助。
答案 1 :(得分:1)
尝试以下代码
class Listen: UIViewController {
@IBOutlet weak var MyMenu: UIBarButtonItem!
@IBOutlet weak var tableView: UITableView!
var items : Array<Item> = []
var entries : Array<Entry> = []
override func viewDidLoad() {
super.viewDidLoad()
loadRSS()
loadAtom()
MyMenu.target = self.revealViewController()
MyMenu.action = #selector(SWRevealViewController.revealToggle(_:))
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
let item:Item = self.items[indexPath.row]
cell.textLabel?.text = item.title
cell.detailTextLabel?.text = self.pubDateStringFromDate(item.pubDate! as Date)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = self.items[indexPath.row]
let url:URL = URL(string: item.link!)!
let safariViewController = SFSafariViewController(url: url, entersReaderIfAvailable: true)
present(safariViewController, animated: true, completion: nil)
}
func loadRSS() {
let feedUrlString:String = "https://vimeo.com/MyChannel/videos/rss"
Alamofire.request(feedUrlString).response { response in
if let data = response.data, let _ = String(data: data, encoding: .utf8) {
TIFeedParser.parseRSS(xmlData: data as NSData, completionHandler: {(isSuccess, channel, error) -> Void in
if (isSuccess) {
self.items = channel!.items!
self.tableView.reloadData()
}
if (response.error != nil) {
print((response.error?.localizedDescription)! as String)
}
})
}
}
}
func loadAtom() {
let feedUrlString:String = "https://vimeo.com/MyChannel/videos/rss"
Alamofire.request(feedUrlString).response { response in
if let data = response.data, let _ = String(data: data, encoding: .utf8) {
TIFeedParser.parseAtom(xmlData: data as NSData, completionHandler: {(isSuccess, feed, error) -> Void in
if (isSuccess) {
self.entries = feed!.entries!
self.tableView.reloadData()
}
if (error != nil) {
print((error?.localizedDescription)! as String)
}
})
}
}
}
func pubDateStringFromDate(_ pubDate:Date)->String {
let format = DateFormatter()
format.dateFormat = "yyyy/M/d HH:mm"
let pubDateString = format.string(from: pubDate)
return pubDateString
}
override var prefersStatusBarHidden: Bool {
return true
}
}