Javascript AngularJS使用路由参数实现客户端包含的方法是什么?
假设我的AngularJS应用程序中有两个页面,一个显示作者的信息,另一个显示书籍的信息。我有一个单独的模板文件、控制器和路由。在作者页面上,我想显示有关他最近写的书的信息。我该怎么做 我的每条路线都嵌入了一个URL参数,该参数告诉控制器要为哪个作者或书籍获取数据:Javascript AngularJS使用路由参数实现客户端包含的方法是什么?,javascript,html,angularjs,angular-ui-router,angularjs-routing,Javascript,Html,Angularjs,Angular Ui Router,Angularjs Routing,假设我的AngularJS应用程序中有两个页面,一个显示作者的信息,另一个显示书籍的信息。我有一个单独的模板文件、控制器和路由。在作者页面上,我想显示有关他最近写的书的信息。我该怎么做 我的每条路线都嵌入了一个URL参数,该参数告诉控制器要为哪个作者或书籍获取数据: .when('/authors/:authorId', { templateUrl: 'author.html', controller: 'AuthorsController') .when('/books/:bookId', {
.when('/authors/:authorId', { templateUrl: 'author.html', controller: 'AuthorsController')
.when('/books/:bookId', { templateUrl: 'book.html', controller: 'BooksController')
据我所知,我不能使用ng include
,因为它不支持路由参数,只支持模板文件。我可以使用带有src=“/books/”
的IFrame,但它感觉应该有一种角度的方式来使用URL参数进行客户端包含。我阅读了uirouter
的wiki页面,但这只涵盖了URL请求的接收端
ng view
似乎也不是正确的解决方案,因为我已经在index.html
格式模板中使用了它。下面是我要显示的HTML的逻辑结构:
<html ng-app="myApp">
<body>
<!-- displays template from the current route, e.g. /authors/1 -->
<div data-ng-view>
<!-- this HTML is loaded from the author.html template -->
Author: George R. R. Martin
(other author details...)
Most recent book:
*** THIS IS MY PROBLEM -- HOW TO INCLUDE /books/1 ? ***
<!-- this HTML is loaded from the book.html template -->
Title: A Dance with Dragons
Pub. date: 2011
...
</div>
</body>
</html>
author.html
中的代码片段:
Author: {{author.name}}
Most recent book:
<!-- all I'm trying to do is to include HTML from a route, but ng-include doesn't support using routes :( -->
<div ng-include='/books/{{mostRecentBookId}}'></div>
All books:
<!-- this is where @Akeem's solution breaks down; the knowledge of which bookId to include comes from the HTML below, not the AuthorsController -->
<div ng-repeat="bookId in allBooks">
<div ng-include='/books/{{bookId}}'></div>
<br/>
</div>
作者:{{Author.name}
最近出版的书:
所有书籍:
编辑
我已经将@Akeem建议的解决方案应用到我的示例中,并添加了关于为什么它对我不起作用的注释:据我所知,尽管ng include创建了一个新的作用域,但它也从其父作用域继承了变量。因此,您可以在AuthorsController中设置
$scope.bookId
,并在BooksController中检查此变量
app.controller('AuthorsController', function($scope) {
$scope.bookId = 123;
});
app.controller('BooksController', function($scope,$routeParams) {
if(!$scope.bookId){
$scope.bookId= $routeParams['bookId'];
}
var books = {'1' : 'To Killing a Mockingbird', '23' : 'Harry Potter', '123':'Catch 22'};
$scope.title = books[$scope.bookId];
});
从那里,您可以将ng include指令与ng controller指令结合起来,在author.html模板中使用BooksController
<div ng-include src='"books.html"' ng-controller='BooksController'></div>
最后,在books.html中,您可以正常引用所有变量
<h1>{{title}}</h1>
<p>This is a book with an id of {{bookId}}</p>
<hr>
{{title}
这是一本id为{{bookId}的书
好的,我从@Akeem的解决方案中找到了缺失的部分:。我已经更新了我的应用程序来使用它,它很有效。以下是如何包含另一个模板,使用ng init设置$scope.bookId
变量,而不是使用路由参数:
<div ng-init="bookId = author.mostRecentBook" ng-include="'book.html'"></div>
这样做的缺点是调用代码与它包含的模板文件更紧密地耦合,而不是使用路由URL作为抽象层。被调用的控制器需要检查scope和route参数,以查看哪个参数用于传入bookId
:
.controller('BooksController', function($scope, $routeParams) {
if (!$scope.bookId) {
$scope.bookId = $routeParams['bookId'];
}
...
})
我的偏好是通过我设置的路径(“/books/:bookId”
)找到一种方法来包含书籍数据,但由于似乎没有这样做的方法,因此必须结合使用ng repeat
和ng init
值得思考的是:可能角度路由并不用于包含单个部分,而仅用于包含每页的单个
ng视图
模板。但是我打赌你可以创建一个如下的指令:
<div ng-include-url="/books/1"></div>
它在
$route
服务中查找URL,并且ng是否包括使用路由的templateUrl
(和controller
)属性。在传递给控制器之前,它还必须从$routeParams
对象中的URL设置bookId
。我既没有时间也没有勇气去完成这件事,但是,使用我已经配置的路由将内容从一个模板/控制器动态加载到另一个模板/控制器似乎很有用。根据格式,我猜您需要一个图书id来显示图书的详细信息,而在作者页面上您没有任何图书id,对吗?因此,即使您需要显示最新书籍的详细信息,那么您发送作者详细信息的web服务也必须至少向您发送作者最新书籍的bookid。您的书籍模板文件是特定于每本书的html?啊,您可以使用共享范围来传达要显示的bookid
,而不是使用路由参数!这肯定会解决我的问题。但是,我发现它有一个问题:它在AuthorsController
和BooksController
之间引入了耦合。如果我想在作者的页面上展示两本最新的书呢?那么BooksController
如何知道在每种情况下显示哪本书呢?@SteveK在这种情况下,您很可能会使用ng repeat和bookIds列表。从这里开始,您将在bookList中拥有bookId,并应用相同的代码。好的,如果我显示一个简单的书籍列表,这将起作用,因为我可以将bookId
分配给ng repeat
循环中的单个书籍。但是,如果我想先显示mostRecentBookId
的书籍详细信息,然后再迭代接下来的其他书籍,该怎么办?在author.html
的源代码中,我正在执行book.html
的ng include
,要显示的图书ID来自不同的$scope
变量:mostRecentBookId
或bookId
(来自ng repeat
)。我更新了我的问题以解决这个用例。
.controller('BooksController', function($scope, $routeParams) {
if (!$scope.bookId) {
$scope.bookId = $routeParams['bookId'];
}
...
})
<div ng-include-url="/books/1"></div>